zoukankan      html  css  js  c++  java
  • 反射

     2.1反射概述
    Java反射机制:是指在运行时去获取一个类的变量 和方法信息。然后通过获取到的信息来创建对象,调用方法的一
    种机制。由于这种动态性,可以极大的增强程序的灵活性,程序不用在编译期就完成确定,在运行期仍然可以扩展

    获取Class类的对象
    我们要想通过反射去使用一个类,首先我们要获取到该类的字节码文件对象,也就是类型为Class类型的对象
    这里我们提供三种方式获取Class类型的对象
    ●使用类的class属 性来获取该类对应的Class对象。举例: Student.class将 会返回Student类对应的Class对象
    ●调用对象的getClass0方法, 返回该象所属类对应的Class对象
    该方法是Object类中的方法,所有的Java对象都可以调用该方法
    ●使用Class类中的静态方法forName(String className),该方法需要传入字符串参数,该字符串参数的值是某
    个类的全路径,也就是完整包名的路径

    package com.test02;
    
    
    public class reflectDemo {
        public static void main(String[] args) throws ClassNotFoundException {
    //        1:使用类的class属性来获取该类对应的Class对象
            Class<Student> c1 = Student.class;
            System.out.println(c1);
            System.out.println("---------");
            Student s = new Student();
            Class<? extends Student> c2 = s.getClass();
    //        调用对象的getClass()方法
            System.out.println(c2);
            System.out.println("-------------");
    //        使用Class类中的静态方法forName(String className)
            Class<?> c3 = Class.forName("com.test02.Student");
            System.out.println(c3);
        }
    }

    反射获取构造方法并使用
    Class类中用于获取构造方法的方法

    数组:
    ●Constructor<?> ] getConstructors(): 返回所有公共构造方法对象的数组
    ●Constructor<?>[ getDeclaredConstructors0: 返回所有构造方法对象的数组

    单个:
    ●Constructor<T> getConstructor(Class <?> .. parameterTypes):返回单个公共构造方法对象
    ●Constructor<T> getDeclaredConstructor(Class<?> .. parameterTypes):返回单个构造方法对象


    Constructor类中用于创建对象的方法
    ●T newlnstance(Objec... initargs):根据指定的构造方法创建对象
    //暴力反射

    public void setAccessible(boolean flag):值为true,取消访问检查

    package com.test02;
    /*
    反射获取构造方法并使用
     */
    
    import java.lang.reflect.Constructor;
    import java.lang.reflect.InvocationTargetException;
    
    public class refelectDemo01 {
        public static void main(String[] args) throws ClassNotFoundException, NoSuchMethodException, IllegalAccessException, InvocationTargetException, InstantiationException {
            //获取class对象
            Class<?> c1 = Class.forName("com.test02.Student");
    
    //        Constructor<?>[] getConstructors​() 返回一个包含 Constructor对象的数组,
    //         Constructor对象反映了由该 Class对象表示的类的所有公共构造函数。
            Constructor<?>[] cons = c1.getConstructors();
    
            //  Constructor<?>[] getDeclaredConstructors​()
    // 返回反映由该 Class对象表示的类声明的所有构造函数的 Constructor对象的数组。
            Constructor<?>[] cons2 = c1.getDeclaredConstructors();
            for(Constructor con:cons2) {
                System.out.println(con);
            }
            System.out.println("-----------");
    
    //        Constructor<T> getConstructor​(Class<?>... parameterTypes)
    //        返回一个 Constructor对象,该对象反映由该 Class对象表示的类的指定公共构造函数。
    
    //        Constructor<T> getDeclaredConstructor​(Class<?>... parameterTypes)
    //        返回一个 Constructor对象,该对象反映由此 Class对象表示的类或接口的指定构造函数。
    
            //Constructor<?> con = c1.getConstructor();
    
    
            //Constructor是供了-一个类的单个构造函数的信息和访问权限
    //        T newInstance​(Object... initargs)
    //        使用由此 Constructor对象表示的构造函数,使用指定的初始化参数来创建和初始化构造函数的声明类的新实例。
            //
    //        基本数据类型也可以通过.Class得到对应的Class类型
                    //练习1
            Constructor<?> con3 = c1.getConstructor(String.class, int.class, String.class);
            Object obj = con3.newInstance("林青霞",30,"西安");
            System.out.println(obj);
            System.out.println("-----------");
    //        练习2 通过反射实现如下的操作:
    //        Student s = new Student( "林青霞");
    //        System. out. println(s);
    
            //暴力反射
    //     public void setAccessible​(boolean flag)将此反射对象的accessible标志设置为指示的布尔值。 值为true表示反射对象
    //     应该在使用Java语言访问控制时抑制检查。 值为false表示反射对象应该在使用Java语言访问控制时执行检查,并在类描述中指出变体。
            Constructor<?> con4 = c1.getDeclaredConstructor(String.class);
            con4.setAccessible(true);//由于下面对私有构造方法
            Object obj1 = con4.newInstance("林青霞");
            System.out.println(obj1);
    
    
        }
    }

    反射获取成员变量并使用
    Class类中用于获取成员变量的方法
      Field[ getFields():返回所有公共成员变对象的数组
      Field[] getDeclaredFields():返回所有成员变量对象的数组
      Field getField(String name):返回单个公共成员变量对象
      Field getDeclaredField(String name):返回单个成员变量对象
    Field类中用于给成员变量赋值的方法
    ●void set(Object obj, Object value):给obj对象的成员变量赋值为value

    package com.test02;
    /*
    反射获取成员变量
     */
    
    import java.lang.reflect.Constructor;
    import java.lang.reflect.Field;
    import java.lang.reflect.InvocationTargetException;
    
    public class reflectDemo02 {
        public static void main(String[] args) throws ClassNotFoundException, NoSuchFieldException, NoSuchMethodException, IllegalAccessException, InvocationTargetException, InstantiationException {
            //获取class对象
            Class<?> c = Class.forName("com.test02.Student");
    //        Field[] getFields​() 返回一个包含 Field对象的数组, Field对象反映由该 Class对象表示的类或接口的所有可访问的公共字段。
    //        Field[] getDeclaredFields​()             返回一个 Field对象的数组,反映了由该 Class对象表示的类或接口声明的所有字段。
    //        Field[] fields = c.getFields();
            Field[] fields = c.getDeclaredFields();
            for (Field field : fields) {
                System.out.println(field);
            }
            System.out.println("---------------");
    //        Field getField​(String name) 返回一个 Field对象,该对象反映由该 Class对象表示的类或接口的指定公共成员字段。
    //        Field getDeclaredField​(String name) 返回一个 Field对象,该对象反映由该 Class对象表示的类或接口的指定声明字段。
    //        Field getField​(String name)
            Field field = c.getField("address");//成员变量的引用对象
    
            //获取无参构造方法创建对象
            //FieLa提供有关类或接口的单个字段的信息和动态访问
            //void set (object obj, object value) 将指定的对象参数中由此Field对象表示的字段设置为指定的新值
    
            Constructor<?> con = c.getConstructor();
            Object obj = con.newInstance();
            field.set(obj, "北京");//给obj的成员变量field赋值为北京
            System.out.println(obj);
    
    
    //        Student s = new Student();
    //····s.address = "西安";
    //····System. out . println(s);
    
            System.out.println("----------------");
    
    //        Field getDeclaredField​(String name)
            Field age = c.getDeclaredField("age");
    
            System.out.println(age); //age对象的引用
        }
    }

    通过反射给成员变量赋值练习

    package com.test02;
    /*
    练习:通过反射实现如下操作
            Students = ngw Student();
            s.name = "林青霞";
            s.age = 30;
            s.address = "西安";
            System.out.printin();
    
     */
    
    import java.lang.reflect.Constructor;
    import java.lang.reflect.Field;
    import java.lang.reflect.InvocationTargetException;
    
    public class reflectDemo03 {
        public static void main(String[] args) throws ClassNotFoundException, IllegalAccessException, InstantiationException, NoSuchMethodException, InvocationTargetException, NoSuchFieldException {
            //获取要反射的类的对象
            Class<?> c = Class.forName("com.test02.Student");
    
            //创建对象示例
    //        通过有参构造赋值
    //        Constructor<?> con = c.getConstructor(String.class, int.class, String.class);
    //        Object obj = con.newInstance("林青霞",30,"西安");
    
            Constructor<?> con = c.getConstructor();
            Object obj = con.newInstance();
            System.out.println(obj);
    
            //通过反射成员变量赋值
    
    
            Field name = c.getDeclaredField("name");
            name.setAccessible(true);
            name.set(obj,"林青霞");
    
            Field age = c.getDeclaredField("age");
            age.setAccessible(true);
            age.set(obj,33);
    
            Field address = c.getField("address");
            address.set(obj,"北京");
            System.out.println(obj);
    
    //
    
    
        }
    }

    反射获取成员方法并使用


    Class类中用于获取成员方法的方法
    ●Method[ getMethods0: 返回所有公共成员方法对象的数组,包括继承的
    ●Method] getDeclaredMethods(): 返回所有成员方法对象的数组,不包括继承的
    ●Method getMethod(String name, Class <?> .. parameterTypes):返回单个公共成员方法对象
    ●Method getDeclaredMethod(String name, Class <?> .. parameterTypes):返回单个成员方法对象
    Method类中用于调用成员方法的方法
    ●Object invoke(Object obj, Object... args):调用obj对象的成员方法,参数是args,返回值是Object类型

    package com.test02;
    
    import java.lang.reflect.Constructor;
    import java.lang.reflect.InvocationTargetException;
    import java.lang.reflect.Method;
    
    public class reflectDemo04 {
        public static void main(String[] args) throws ClassNotFoundException, NoSuchMethodException, IllegalAccessException, InvocationTargetException, InstantiationException {
            //获取class对象
            Class<?> c = Class.forName("com.test02.Student");
    //   Method[] getMethods​() 返回一个包含 方法对象的数组, 方法对象反映由该 Class对象表示的类或接口的所有公共方法,
    //             包括由类或接口声明的对象以及从超类和超级接口继承的类。
    //   Method[] getDeclaredMethods​() 返回一个包含 方法对象的数组, 方法对象反映由 Class对象表示的类或接口的所有声明方法,
    //      包括public,protected,default(package)访问和私有方法,但不包括继承方法。
            Method[] Methods = c.getDeclaredMethods();
            for (Method method : Methods) {
                System.out.println(method);
            }
    
    //        Method getMethod​(String name, Class<?>... parameterTypes) 返回一个 方法对象,
    //              该对象反映由该 Class对象表示的类或接口的指定公共成员方法。
    //        Method getDeclaredMethod​(String name, Class<?>... parameterTypes) 返回一个 方法对象,
    //              它反映此表示的类或接口的指定声明的方法 Class对象。
            Method m = c.getMethod("method1");
            //获取无参构造方法创建对象
    
            Constructor<?> con = c.getConstructor();
            Object obj = con.newInstance();
            //在类或接口上提供有关单- 方法的信息和访问权限
    //        Object invoke​(Object obj, Object... args) 在具有指定参数的指定对象上调用此 方法对象表示的基础方法。
            //0bject: 返回值类型
            //obj:调用方法的对象
            //args:方法需要的参数
    
            m.invoke(obj);
    
    
    //        Student s = new Student();
    //        s. method1( ) ;
    
    
        }
    }

     练习:通过反射实现如下操作

    Student s = new Student();

    s . method1();

    s. method2("林青霞");

    String ss = s.method3( "林青霞", 30);

    System. out. println(ss);

    s. function();

    package com.test02;
    /*
    练习:通过反射实现如下操作
    Student s = new Student();
    s . method1();
    s. method2("林青霞");
    String ss = s.method3( "林青霞", 30);
    System. out. println(ss);
    s. function();
    
     */
    
    import java.lang.reflect.Constructor;
    import java.lang.reflect.InvocationTargetException;
    import java.lang.reflect.Method;
    
    public class reflectDemo05 {
        public static void main(String[] args) throws ClassNotFoundException, NoSuchMethodException, IllegalAccessException, InvocationTargetException, InstantiationException {
            //获取类的对象
            Class<?> c = Class.forName("com.test02.Student");
    
    //        Student s = new Student();
            Constructor<?> con = c.getConstructor() ;
            Object obj = con.newInstance();
    
    //        s . method1();
    //        invoke调用对象
            Method method1 = c.getMethod("method1");
            method1.invoke(obj);
    
    //        s. method2("林青霞");
            Method method2 = c.getMethod("method2", String.class);
            method2.invoke(obj,"林青霞");
    //        String ss = s.method3( "林青霞", 30);
            Method method3 = c.getMethod("method3", String.class, int.class);
            Object ss = method3.invoke(obj, "林青霞", 30);
            System.out.println(ss);
    
    //        s. function();
            Method function = c.getDeclaredMethod("function");
            function.setAccessible(true);
            function.invoke(obj);
    
    
        }
    }

    反射练习之越过泛型检查

    package com.test02;
    /*
    练习1:我有一个Arraylist<Integer>集合, 现在我想在这个集合中添加一-个字符串数据,如何实现?
    
     */
    
    import java.lang.reflect.InvocationTargetException;
    import java.lang.reflect.Method;
    import java.util.ArrayList;
    
    public class refiectDemo06 {
        public static void main(String[] args) throws NoSuchMethodException, InvocationTargetException, IllegalAccessException {
            //创建集合
            ArrayList<Integer> array = new ArrayList<Integer>();
            array.add(10);
            array.add(20);
            array.add(30);
    //        array.add("hello");
    
            Class<? extends ArrayList> c = array.getClass();
            
            Method m = c.getMethod("add", Object.class);
    
            m.invoke(array, "hello");
            System.out.println(array);
        }
    }

    反射运行配置文件

  • 相关阅读:
    干点小事的常用的着的语句
    hadoop测试环境主配置简例
    开源集
    Linux系统重装与还原
    POJ1679 The Unique MST 【次小生成树】
    No value for key [org.hibernate.impl.SessionFactoryImpl 异常解决
    Java程序猿学习C++之数组和动态数组
    LightOj 1123-Trail Maintenance(最小生成树:神级删边)
    分布式协议之两阶段提交协议(2PC)和改进三阶段提交协议(3PC)
    HDU 4847 陕西邀请赛A(水)
  • 原文地址:https://www.cnblogs.com/lsswudi/p/11454997.html
Copyright © 2011-2022 走看看