反射机制
1.什么是反射?
必须是运行的状态下,都能够获取到这个类的所有的属性和方法。
对于类中的任意一个对象对象,都能够调用它的任意一个方法和属性。
这种动态获取的信息以及这种动态调用的对象的方法的功能就是java中反射
必须是运行的状态下,都能够获取到这个类的所有的属性和方法。
对于类中的任意一个对象对象,都能够调用它的任意一个方法和属性。
这种动态获取的信息以及这种动态调用的对象的方法的功能就是java中反射
2.理解Class类?
Class 对象只能由系统建立对象
–一个类在 JVM 中只会有一个Class实例
–每个类的实例都会记得自己是由哪个 Class 实例所生成
3..该才能怎样执行反射机制?
就必须先要获取到该类的字节码文件对象(。class),
每一一个类对应着一个字节码文件也就对应着一个Class类型的对象,也就是字节码对象
就必须先要获取到该类的字节码文件对象(。class),
每一一个类对应着一个字节码文件也就对应着一个Class类型的对象,也就是字节码对象
3.获取字节码文件对象的三种方式
Class cla = Class.forName("包名+类名");//此时为源文件阶段,并没有改变字节码文件
Class cla1 = person.class;//获取自己,字节码阶段
Class cla2 = p.getClass();//创建对象的状态
有了字节码文件对象才能获得类中所有的信息
Class cla = Class.forName("包名+类名");//此时为源文件阶段,并没有改变字节码文件
Class cla1 = person.class;//获取自己,字节码阶段
Class cla2 = p.getClass();//创建对象的状态
有了字节码文件对象才能获得类中所有的信息
4.掌握 Constructor、Method、Field 类的用法
Constructor
Constructor
1).Field[] getFields():获取所有的"公有字段"
2).Field[] getDeclaredFields():获取所有字段,包括:私有、受保护、默认、公有;
2.获取单个的:
1).public Field getField(String fieldName):获取某个"公有的"字段;
2).public Field getDeclaredField(String fieldName):获取某个字段(可以是私有的)
设置字段的值:
Field --> public void set(Object obj,Object value):
参数说明:
1.obj:要设置的字段所在的对象;
2.value:要为字段设置的值;
new 和newInstance的区别:
从jvm的角度看,我们使用new的时候,这个要new的类可以没有加载;
但是使用newInstance时候,就必须保证:1、这个类已经加载;2、这个类已经连接了。而完成上面两个步骤的正是class的静态方法forName()方法,这个静态方法调用了启动类加载器(就是加载java API的那个加载器)。
有了上面jvm上的理解,那么我们可以这样说,newInstance实际上是把new这个方式分解为两步,即,首先调用class的加载方法加载某个类,然后实例化。
这样分步的好处是显而易见的。我们可以在调用class的静态加载方法forName时获得更好的灵活性,提供给了我们降耦的手段。
2).Field[] getDeclaredFields():获取所有字段,包括:私有、受保护、默认、公有;
2.获取单个的:
1).public Field getField(String fieldName):获取某个"公有的"字段;
2).public Field getDeclaredField(String fieldName):获取某个字段(可以是私有的)
设置字段的值:
Field --> public void set(Object obj,Object value):
参数说明:
1.obj:要设置的字段所在的对象;
2.value:要为字段设置的值;
new 和newInstance的区别:
从jvm的角度看,我们使用new的时候,这个要new的类可以没有加载;
但是使用newInstance时候,就必须保证:1、这个类已经加载;2、这个类已经连接了。而完成上面两个步骤的正是class的静态方法forName()方法,这个静态方法调用了启动类加载器(就是加载java API的那个加载器)。
有了上面jvm上的理解,那么我们可以这样说,newInstance实际上是把new这个方式分解为两步,即,首先调用class的加载方法加载某个类,然后实例化。
这样分步的好处是显而易见的。我们可以在调用class的静态加载方法forName时获得更好的灵活性,提供给了我们降耦的手段。
newInstance: 弱类型。低效率。只能调用无参构造。
new: 强类型。相对高效。能调用任何public构造。
代码示例:
package cn.reflection; public class Person { public String name; char sex; private int health; protected int age; }
package cn.reflection; import java.lang.reflect.Field; public class Reflect { public static void main(String[] args) throws Exception{ //方式一获取字节码 Person ePerson=new Person(); Class class1=ePerson.getClass(); System.out.println(class1); //方式二 Class class2=Person.class; System.out.println(class2); //方式三 使用几率大 Class class3=Class.forName("cn.reflection.Person"); System.out.println(class3); System.out.println("-----------------华丽的分割线------------"); System.out.println("获取公有字段!!"); Field[] publicfield=class3.getFields(); for (Field field : publicfield) { System.out.println(field); } System.out.println("-----------------华丽的分割线------------"); System.out.println("获取所有字段!!"); publicfield=class3.getDeclaredFields(); for (Field field1 : publicfield) { System.out.println(field1);// 访问字段名.getName() } System.out.println("-----------------华丽的分割线------------"); System.out.println("获取指定呆的公有字段并给他赋值!"); Field pFields=class3.getField("name"); System.out.println(pFields); //实例化一个object类 Object object=class3.newInstance(); pFields.set(object, "你好"); Person person=(Person)object; System.out.println("hello"+pFields.get(person)); } }