聊聊java的反射
类的加载
当程序访问或者初始化任何一个类,jvm都会将类加载到内存。表面上类是对象的抽象,对象是类的实例。实际上将类的class文件加载到内存会为类创建一个java.lang.Class对象,因此在内存中类也是一个对象。比如人类就是每一个人的抽象,是对类实例的描述。但是想要描述类,类本身也得需要一个对象才能描述。就像”人类”这个词本身就是对一类事物的描述,但是想要描述“人类”这个类,又需要一个对象对”人类”进行描述。就像前面说的,实际上将类的class文件加载到内存会为类创建一个java.lang.Class对象。
类会在下面的情况下初始化
- new关键字创建类实例
- 调用类的静态方法,属性(能确定值的 final定义的属性除外)
对于定义为final的属性,如果编译期间可以确定属性值,java编译器会在编译阶段把field替换成对应的值,因此即使程序使用静态final属性,类也不会实例化。 - 初始化类的子类(子类初始化先加载父类)
- 使用反射访问类(初始化类实例,获取属性等)
反射
之前说了,类加载实际是将java类在内存中创建一个java.lang.Class对象,获取任意类的Class对象有下面几中方式
- 调用某个类的class属性, 如Person.class;
- 使用Class的forName方法, 如 Class.forName(“Person”);
- 对象的getClass方法, 如果 persion.getClass();
获取到类的Class对象也就获取到了类的描述信息,如此拿到对应的类结构。