反射的定义
正常方式:
引入类所对应的包名————实例化一个该类的对象————得到一个新的对象
反射方式:
一个对象————getClass()方法————得到该类所属的包名
对象反射以后可以得到的信息:该类的属性、方法和构造器,以及该类实现了哪些接口。
对于每个类而言,不管它实例化了多少数量的对象,java都为其保留有且仅有一个不变的Class类的对象。每个Class对象都对应着JVM(Java虚拟机)创建的一个.class文件。
类的加载与ClassLoader的理解
加载
将class文件的字节码内容加载到内存中去,然后生成一个代表这个类的class对象。
链接(将Java类的二进制代码合并到JVM的运行状态之中的过程)
这个阶段会为类变量分配内存并进行初始化赋值,并将常量池中的常量的符号引用替换为直接引用。
初始化
执行类的构造器<clinit>()方法的过程。类构造器<clinit>()方法是由编译期自动收集类中所有类变量的赋值动作和静态代码块(static{})中的语句合并产生的。
什么时候会发生类的初始化?
类的主动引用(会发生类的初始化)
1、虚拟机启动时,会初始化main方法所在的类
2、new一个类的对象
3、调用类的静态成员(除了final常量)和静态方法
4、使用java.lang.reflect包的方法对类进行反射调用
5、当初始化一个类,如果其父类没有被初始化,那么会先初始化它的父类。
类的被动引用(不会发生类的初始化)
1、通过子类引用父类的初始化时,不会导致子类初始化
2、通过数组定义类引用,不会触发此类的初始化。
eg:现在有一个Student类。则下面代码不会触发该类的初始化:
Student[] student = new Student[10];
3、访问类的final常量时,不会触发类的初始化。(已在链接阶段的最后一步将常量存入类的调用池中了)