反射

1. 什么是反射: 所有反射中用到的类都在这个包中:java.lang.reflect

        通过加载某个类,在内存中生成类的对象,我们可以对类中的结构进行操作。
        这些结构包括:构造方法、属性、方法等
        1) 类: Class (在内存中生成的字节码对象)
        2) 构造方法:  Constructor
        3) 属性: Field
        4) 方法: Method
                  
2. 反射在实际开发中的应用:
        1) 用于开发IDE,如:eclipse、netbean
        2) 用于框架的开发:Struts、Hibernate等
        3) 用于一些小工具的开发

 

Class类: 

1. 类的加载:
        源代码 (编译) --> 字节码(类加载器) --> 类对象

 

2. 得到Class对象的三种方式: 无论使用上面哪种方式加载类对象,始终得到同一个类对象。第三种方式耦合性最低

        1) 类名.class 可以得到一个类对象
            如:Class c1 = Employee.class;
        2) 通过对象getClass()方法得到类对象
            Employee emp = new Employee();
            Class c2 =  emp.getClass();
        3) 通过Class中静态方法
            Class.forName("类全名");

 

3. Class类中的方法:
        1) getName() 得到类的全名
        2) getSimpleName() 得到类的简单名,没有包名

 

 

Constructor构造方法的类

  1. 作用:    代表一个类对象中的构造方法
       
  2. 得到Constructor类的方法:
        1) Class类中的方法:得到一个构造方法
            getConstructor(Class... 变量类型) 只能得到公共的构造方法
            getDeclaredConstructor(Class...变量类型) 得到声明的构造方法,无论什么修饰符
           
            得到多个构造方法
            Constructor[] getConstructors() 得到所有公共构造方法
            Constructor[] getDeclaredConstructors() 得到所有声明的构造方法
            
       2) 实例化对象的方法:
            a. 通过构造方法创建对象:
                得到构造方法以后,可以对类进行实例化。
                Object newInstance(Object...对象),返回一个已经实例化好的对象

 

            b.Class创建对象:只能是无参构造

                Class对象.newInstance();
           
            c. 暴力反射
                setAccessible(true)
           
  3. 基本类型与引用类型类对象
        在反射中int.class和Integer.class是两种不同的类型

 

  4. Declared的规律:
        如果一个方法上有Declared这个单词,则表示可以得到所有声明的对象。如果没有这个单词,则只能得到public类型的对象

Method方法类

得到一个指定的方法

    公有的方法:    clazz.getMethod(方法名, Class...方法的参数类型); 方法有重载

    声明的方法:    clazz.getDeclaredMethod(方法名, Class...方法的参数类型);

 

得到所有方法

   所有公有的方法:    Method[]  clazz.getMethods();

    所有声明的方法:    Method[]  clazz.getDeclaredMethods();

 

Method类的方法:

    方法对象.invoke(实例对象, 方法参数);

  1 调用实例方法
  2   Employee emp = new Employee();
  3   m1.invoke(emp,"西瓜");
  4 
  5 调用静态方法
  6   m3.invoke(null, 12);  可以使用对象,也可以不使用对象,指定为null
调用实例方法
  1     public static void main(String[] args) throws Exception {
  2         //1.得到类对象
  3         Class clazz = Class.forName("com.itheima.b.Employee");
  4         //实例化对象
  5         Constructor c1 = clazz.getConstructor();
  6         Object obj = c1.newInstance();
  7         //2. 得到方法对象
  8         Method m1 = clazz.getMethod("eat", String.class);
  9         System.out.println(m1);
 10         //3. 调用方法
 11         m1.invoke(obj, "西瓜");
 12 
 13         //得到声明的方法
 14         Method m2 = clazz.getDeclaredMethod("work", int.class);
 15         System.out.println(m2);
 16         //暴力反射
 17         m2.setAccessible(true);
 18         //调用私有的方法
 19         m2.invoke(obj, 8);
 20 
 21         //得到静态方法
 22         Method m3 = clazz.getDeclaredMethod("sleep", int.class);
 23         System.out.println(m3);
 24         //调用静态方法
 25         m3.invoke(null, 12);
 26 
 27         System.out.println("===============");
 28         //得到所有的方法
 29         //Method[] methods = clazz.getMethods();
 30         Method[] methods = clazz.getDeclaredMethods();
 31         for (Method method : methods) {
 32             System.out.println(method);
 33         }
 34     }
 35 
代码

 

Field属性类

得到指定的字段(对象)

    clazz.getField(属性名);

获取所有公有字段

    clazz.getFields();

获取所有声明的字段

    clazz.getDeclaredFields();

 

给属性赋值

    基本属性赋值:    setInt(),  setDouble()  . . . .

    引用属性赋值:    set(obj, value)       (引用属性就是String这些)

  1     public static void main(String[] args) throws Exception {
  2         //1.得到类对象
  3         Class  clazz = Class.forName("com.itheima.b.Employee");
  4         //实例化对象
  5         Object obj = clazz.newInstance();   //使用默认的构造方法实例化对象
  6         //2.得到其中的一个属性
  7         Field f1 = clazz.getField("name");
  8         System.out.println(f1);
  9         //3. 属性:获取它的值,设置它的值
 10         //给引用类型赋值
 11         f1.set(obj, "孙悟空");
 12         System.out.println(obj);
 13         //得到年龄
 14         Field f2 = clazz.getDeclaredField("age");
 15         System.out.println(f2);
 16         //暴力反射
 17         f2.setAccessible(true);
 18         //赋值
 19         f2.setInt(obj, 500);
 20         System.out.println(obj);
 21         System.out.println("=============");
 22         //得到所有公共的属性
 23         //Field[] fields = clazz.getFields();
 24         Field[] fields = clazz.getDeclaredFields();
 25         for (Field field : fields) {
 26             System.out.println("变量名:" + field.getName() + "\t变量类型:" + field.getType());
 27         }
 28     }
代码
posted @ 2017-05-21 21:27  我是明仔  阅读(124)  评论(0)    收藏  举报