Class类
反射是指Java在有程序运行期间拿到一个对象的所有信息。反射是为了解决在运行期间对某个实例一无所知的情况下,如何调用其方法。
除了int
等基本类型之外,Java的其它类型全部都是class
。class是由JVM在执行过程中,动态加载的。JVM在第一次遇到某个class的时候,会把这个class加载进内存中。每加载一种class到内存中,JVM就会为该class创建一个Class类型的实例。
public final class Class {
private Class() {}
}
只有JVM才能够创建Class类型的对象。每个Class对象都指向一个特定的类型,包含了该类型的完整信息。通过Class获取class信息的方式叫做反射。
Class cls = String.class;
String s = "Hello";
Class aClass = s.getClass();
//Class cls1 = Class.forName("java.lang.String");
Class类型的对象是唯一的,可以使用==比较两个对象(只比较具体类型)。使用instanceof
比较两个Class对象的时候,会将其子类一起比较。
通过某个Class类型的实例获取class信息的参考代码:
static void printObjectInfo(Object object) {
Class cls = object.getClass();
printClassInfo(cls);
}
static void printClassInfo(Class cls) {
System.out.println("Class name: " + cls.getName());
System.out.println("Simple name: " + cls.getSimpleName());
if(cls.getPackage() != null) {
System.out.println("Package name: " + cls.getPackage());
}
System.out.println("is interface: " + cls.isInterface());
System.out.println("is enum" + cls.isEnum());
System.out.println("is primitive" + cls.isPrimitive());
}
也可以通过某个Class实例,创建对应class的实例,但是这只能调用class类型的public无参构造方法。
动态加载
JVM只有在第一次用到某个class的时候才加载该class。这是JVM加载class的特性。这种特性运行我们在运行期间根据条件加载不同的实现类。
调用构造方法
import java.lang.reflect.Constructor;
public class Main {
public static void main(String[] args) throws Exception {
// 获取构造方法Integer(int):
Constructor cons1 = Integer.class.getConstructor(int.class);
// 调用构造方法:
Integer n1 = (Integer) cons1.newInstance(123);
System.out.println(n1);
// 获取构造方法Integer(String)
Constructor cons2 = Integer.class.getConstructor(String.class);
Integer n2 = (Integer) cons2.newInstance("456");
System.out.println(n2);
}
}