一、正射
反射之中包含了一个「反」字,所以想要解释反射就必须先从「正」开始解释。
一般情况下,我们使用某个类时必定知道它是什么类,是用来做什么的。于是我们直接对这个类进行实例化,之后使用这个类对象进行操作。
A a = new A();
a.setA("muzi");
上面这样子进行类对象的初始化,我们可以理解为「正」。
二、反射
而反射则是一开始并不知道我要初始化的类对象是什么,自然也无法使用 new 关键字来创建对象了。
这时候,我们使用 JDK 提供的反射 API 进行反射调用:
//得到A类的Class对象
Class a = DayTwo.A.class;
//输出a的名字(即A的全限定名)
System.out.println(a.getName());
控制台输出
DayTwo.A
Process finished with exit code 0
上面就是,通过类得到类的Class对象,这里的Class对象可以理解成存储每个类的类信息的类,通过类对象(a)使用jdk提供的反射API可以得到该类的所有信息(域、方法、构造方法、父类、修饰符等等)
三、常用反射API
1、通过反射获取Class对象
在反射中,要获取一个类或调用一个类的方法,我们首先需要获取到该类的 Class 对象。
在 Java API 中,获取 Class 类对象有三种方法:
第一种:使用 Class.forName 静态方法。
当你知道该类的全路径名时,你可以使用该方法获取 Class 类对象。
String className = "DayTwo.A";
Class a = Class.forName(className);
第二种:使用.class
这种方法只适合在编译前就知道操作的类。
Class a = A.class;
第三种:使用类对象.getClass()方法
A a = new A();
Class aClass = a.getClass();
2、通过反射创建类对象
通过反射创建类对象主要有两种方式:通过 Class 对象的 newInstance() 方法、通过 Constructor 对象的 newInstance() 方法。
第一种:通过 Class 对象的 newInstance() 方法。
Class a = A.class;
A o = (A) a.newInstance();
第二种:通过 Constructor 对象的 newInstance() 方法
Class a = A.class;
Constructor constructor = a.getConstructor();
A o = (A) constructor.newInstance();
3、通过反射获取类属性、方法、构造器
1、获取属性(Field)
Field[] fields = cl.getDeclaredFields();
String modifiers = Modifier.toString(field.getModifiers());
public static void printFields(Class cl){
//得到所有属性
Field[] fields = cl.getDeclaredFields();
for (Field field : fields) {
Class type = field.getType();
String name = field.getName();
System.out.print(" ");
//得到属性的权限修饰符
String modifiers = Modifier.toString(field.getModifiers());
if (modifiers.length() > 0) System.out.print(modifiers + " ");
System.out.println(type.getName() + " " + name + ";");
}
}
2、获取方法
Method[] methods = cl.getDeclaredMethods();
String modifiers = Modifier.toString(method.getModifiers());
public static void printMethods(Class cl){
//得到所有方法
Method[] methods = cl.getDeclaredMethods();
for (Method method : methods) {
Class retType = method.getReturnType();
String name = method.getName();
System.out.print(" ");
String modifiers = Modifier.toString(method.getModifiers());
if (modifiers.length() > 0) System.out.print(modifiers + " ");
System.out.print(retType.getName() + " " + name + "(");
Class[] paramTypes = method.getParameterTypes();
for (int i = 0; i < paramTypes.length; i++) {
if (i > 0) System.out.print(",");
System.out.print(paramTypes[i].getName());
}
System.out.println(");");
}
}
3、获取构造方法
Constructor[] constructors = cl.getDeclaredConstructors();
String modifiers = Modifier.toString(constructor.getModifiers());
public static void printConstructors(Class cl){
Constructor[] constructors = cl.getDeclaredConstructors();
for (Constructor constructor : constructors) {
String name = constructor.getName();
System.out.print(" ");
String modifiers = Modifier.toString(constructor.getModifiers());
if (modifiers.length() > 0) System.out.print(modifiers + " ");
System.out.print(name + "(");
Class[] paramTypes = constructor.getParameterTypes();
for (int i = 0; i < paramTypes.length; i++) {
if (i > 0) System.out.print(",");
System.out.print(paramTypes[i].getName());
}
System.out.println(");");
}
}