概念
JVM在第一次读取到一种class类型时,将其加载进内存。每加载一种class,JVM就为其创建一个Class类型的实例,保存该class的所有信息,包括类名,包名,父类,方法,字段等,并关联起来。只有JVM才能创建Class实例。
通过Class实例获取class信息的方法称为反射(Reflection)。
获取Class实例的方法
- 已知class
Class cls = String.class;
- 已知实例变量
String str = "Hello";
Class cls = str.getClass();
- 已知完整类名
Class cls = Class.forName(“java.lang.String");
因为Class实例在JVM中是唯一的,所以,上述方法获取的Class实例是同一个实例。
使用Class实例创建对应类型的实例
如果获取到了一个Class实例,我们就可以通过该Class实例来创建对应类型的实例:
// 获取String的Class实例:
Class cls = String.class;
// 创建一个String实例:
String s = (String) cls.newInstance();
上述代码相当于new String()。通过Class.newInstance()可以创建类实例,它的局限是:只能调用public的无参数构造方法。带参数的构造方法,或者非public的构造方法都无法通过Class.newInstance()被调用。
动态加载
VM在执行Java程序的时候,并不是一次性把所有用到的class全部加载到内存,而是第一次需要用到class时才加载。利用JVM动态加载class的特性,我们可以在运行期控制条件加载不同的实现类。
访问字段
Field getField(name) //根据字段名获取某个public的field(包括父类)
Field getDeclaredField(name) //根据字段名获取当前类的某个field(不包括父类,可以不是public)
Field[] getFields() //获取所有public的field(包括父类)
Field[] getDeclaredFields() //获取当前类的所有field(不包括父类)
再通过get()获取field对象的各种信息
调用方法
Method getMethod(name, Class...):获取某个public的Method(包括父类)
Method getDeclaredMethod(name, Class...):获取当前类的某个Method(不包括父类)
Method[] getMethods():获取所有public的Method(包括父类)
Method[] getDeclaredMethods():获取当前类的所有Method(不包括父类
调用构造方法
getConstructor(Class...):获取某个public的Constructor;
getDeclaredConstructor(Class...):获取某个Constructor;
getConstructors():获取所有public的Constructor;
getDeclaredConstructors():获取所有Constructor
获取父类class
Class i = Integer.class;
Class n = i.getSuperclass();