Java中的反射机制是指
在运行状态中,对于任意一个类,都能够知道这个类所有的属性和方法。
对于任意一个对象,都能知道调用它的任意一个属性和方法。
想理解反射,那么就要对JVM有一定的基础和理解。
而且不要想着速成,一下子会了,面试可以用, 这样反而欲速则不达了。
下面是JVM的架构图。
这样,我们举一个例子。这个是java对象的创建过程。
Object o = new Object();
那么它在内存中是如何创建的呢?过程是啥样的?
首先,JVM启动,代码会编译成一个.class文件。然后被类加载器加载进jvm内存中。 类Object加载到方法区中。创建了Object类的class对象到堆中,注意这个不是new出来的对象,而是类的类型对象,每个类只有一个class对象, 作为方法区类的数据结构的接口。
jvm创建对象前,会检查类是否加载,寻找类对应的class对象,若加载好了,则为你的对象分配内存,初始化也是就是new Object();
加载class文件的步骤:
1. 检查是否已经加载,有就直接返回,避免重复加载。
2. 当前缓存中确实没有该类,那么遵循父优先加载机制,加载.class文件。
3. 上面两步都失败了,调用findClass()方法加载。
需要注意的是,ClassLoader类本身就是抽象类,抽象类无法通过new来创建对象。所以他的findClass()方法写的很随意,直接抛出了异常,反正你无法通过ClassLoader对象调用。也就是说,父类ClassLoader中的findClass()方法根本不会去加载.class文件。
要想理解反射,那么就先从正射开始解释。
class Person {
}
public class TestDemo {
public static void main(String[] args) throwsException {
Person per = new Person() ; // 正着操作
System.out.println(per.getClass().getName()); // 反着来
}
}
反射常用API:
获取反射中的Class对象。
第一种 使用 Class.forName 静态方法。当你知道该类的全路径名时,你可以使用该方法获取 Class 类对象。
Class clz = Class.forName("java.lang.String");
第二种,使用 .class 方法。
这种方法只适合在编译前就知道操作的 Class。
Class clz = String.class;
第三种,使用类对象的 getClass() 方法。
String str = new String("Hello");
Class clz = str.getClass();