日常敲码中,如果想要在程序运行阶段访问某个类的所有信息,并支持修改类的状态或者行为的话,肯定会用到反射,而反射靠的就是Class类。Java的动态代理也用到了这个东西,所以了解其基本操作在苦逼的CRUD中会添加一丝丝乐趣(有点意思)。
首先来看看Class的操作有哪些?
public final class Class<T> {}
上述代码可知,Class是一个由final修饰的泛型类,所以并不能直接通过new Class()获取其实例。那么应该如何获取呢?
//直接通过类的静态变量来获取
Class<Integer> intClass = Integer.class;
//通过实例变量的getClass方法
Integer integer = new Integer(0);
Class<? extends Integer> aClass = integer.getClass();
//通过Class.forName("类的全限定名")
Class<?> aClass1 = Class.forName("java.lang.Integer");
上述三种就是获取某个Class的class实例的方式,需要注意的是,JVM只会加载一个Class实例,也就是说上述三种方式获取到的class实例都是一样的。
而在运用反射的时候,Class.forName是最常用的一种方式。而Class.forName底层会指向forName0这个本地方法
(1)name:类的全限定名
(2)initialize:是否初始化这个类
(3)loader:类加载器
(4)caller:调用Class.forName所在类的Class,比如A类代码块里有Class.forName,那么caller就是A的class实例。
通过Class类可以获取类的实例,构造方法,字段,成员方法,接口等信息。获取之后可以通过API进行相应的操作。
接下来看一下获取到class实例之后怎么获取当前类的实例以及构造方法。
上述两种方式都是调用默认的无参构造进行实例化对象,那么怎么通过公共或私有的有参构造获取实例呢?
//属性
int a;
String b ;
//公共有参构造
public ClassSource(int a) {
this.a = a;
}
//私有有参构造
private ClassSource(String b) {
this.b = b;
}
public static void main(String[] args){
Class<?> aClass = Class.forName("com.liu