每个Java类被加载后,JVM都会为该类生成一个对应的Class对象。通过Class对象,我们就可以探究这个类的信息,然后完成操作。所以,反射操作的步骤就分为了以下三步:
-
获得你想操作的类的java.lang.Class对象;
-
探究这个类的信息,包括但不限于:所属包、父类、实现的接口、内部类、外部类、属性、构造、方法、修饰符等,当然最常用的还是属性、构造和方法。
-
使用探究到的信息完成功能实现,比如:探究到构造就可以产生类的实例对象;探究到属性就可以给属性进行赋值取值;探究到方法就可以进行方法调用。
获取Class对象
Class类,只提供了私有构造方法,所以不能通过new的方式创建。获取一个类的Class对象主要有三种方式:
利用类型.class获取
// String类的Class对象
Class strClass = String.class;
//自定义Student类的Class对象
Class stuClass = Student.class;
//数组的Class对象
Class intArrayClass = int[].class;
//枚举的Class对象
Class enumClass = RetentionPolicy.class;
//注解的Class对象
Class annotationClass = Override.class;
//接口的Class对象
Class serializableClass = Serializable.class;
//基本数据类型获取Class对象
Class intClass = int.class;
// 其中基本数据类型的Class对象在JDK1.5前,使用包装类.TYPE
Class intClass2 = Integer.TYPE;
// 包装类型获取Class对象
Class IntegerClass = Integer.class;
//返回类型void也能获取Class对象
Class voidClass = void.class;
利用对象.getClass()获取
//String类的Class对象
Class strClass = "hello".getClass();
//自定义Student类的Class对象
Student stu = new Student("张三");
Class stuClass = stu.getClass();
//数组的Class对象
double[] array = {1.2, 2.3, 3.4};
Class intArrayClass = array.getClass();
//枚举的Class对象
Class enumClass = RetentionPolicy.SOURCE.getClass();
由于getClass()方法是来自于根类Оbject ,所以只有继承自Object的子类型的对象才能调用。因此该方式不能获取到基本数据类型以及void的Class对象;另外,接口的实现类虽然能调用到getClass()方法,但是获取到的是该实现类的Class对象而不是该接口的,注解Annotation是一种特殊的接口,同理也不能用本方式获取。
思考:如果父类引用指向子类对象,调用该引用的getClass()方法得到的是父类还是子类的Class对象? 回答∶子类。此时,真正被调用的是子类对象身上的getClass()方法,得到的就应该是该子类对象的类模板对象,父类引用只是帮助找到这个子类对象。
利用Class.forName()获取
try {
// String类的Class对象
Class strClass = Class.forName("java.lang.String");
//自定义Student类的Class对象
Class stuClass = Class.forName("com.project.bean.Student");
//接口的Class对象
Class serializableClass = Class.forName("java.io.Serializable");
//枚举的Class对象
Class enumClass = Class.forName("java.lang.annotation.RetentionPolicy");
//注解的Class对象
Class annotationClass = Class.forName("java.lang.Override");
//int[]的Class对象
Class intArrayClass = Class.forName("[I");
// Student[]的Class对象
Class stuArrayClass = Class.forName("[Lcom.project.bean.Student;");
System.out.println(stuArrayClass);
} catch (ClassNotFoundException e) {
e.printStackTrace();
}