前言
Java让我们在运行时识别对象和类的信息,主要有2种方式:
1 | 传统的RTTI,它假定我们在编译时已经知道了所有的类型信息; |
目的
简单介绍一下反射的机制和应用.
正文
class对象
class对象包含了与类有关的信息,是用来创建所有“常规”对象的.每个类都会产生一个对应的Class对象,也就是保存在.class文件。所有类都是在对其第一次使用时,动态加载到JVM的,当程序创建一个对类的静态成员的引用时,就会加载这个类.Class对象仅在需要的时候才会加载,static初始化是在类加载时进行的
扩展
1 | public class TestClass { |
上面代码运行的结果:
结论:
- 说明当第一次引用一个类的静态属性时,该类会加载到jvm中并调用静态块
- 初始化类时会调用相应构造方法,由于该类已经加载到jvm中,所以不会调用静态块
- 第三点同时印证了第二点,第一次初始化某个类时,该类加载到jvm中,首先调用静态块方法,然后调用相应构造方法
- 第四点印证第二点
获取class对象引用的两种方式及区别
1 | 使用功能”.class”来创建Class对象的引用 |
区别:
想在运行时使用类型信息,必须获取对象(比如类Base对象)的Class对象的引用,使用功能Class.forName(“Base”)可以实现该目的,或者使用base.class。注意,有一点很有趣,使用功能”.class”来创建Class对象的引用时,不会自动初始化该Class对象,使用forName()会自动初始化该Class对象。为了使用类而做的准备工作一般有以下3个步骤:
1 | 加载:由类加载器完成,找到对应的字节码,创建一个Class对象 |
扩展
1 | public class BaseMain { |
执行结果:
结论
1 | obj.class确实不会初始化类 |
反射获取私有属性和方法
1 | public class ReflectDemo { |
执行结果: