java反射机制的功能极其强大,可以用来在运行中分析类的能力、在运行中查看对象、实现通用的数组操作代码、利用Method对象等。在这里主要说下反射机制最重要的内容-检查类的结构(利用反射分析类的能力)。
在java.lang.reflect包中有三个类Field、Method和Constructor分别用于描述类的域、方法和构造器。这三个类都有一个getName的方法,用来返回项目(域、方法或构造器)的名称。Field类有一个getType方法,用来描述域所属类型的Class对象。Method和Constructor类有一个getParameterTypes的方法,能够得到参数类型,Method有一个getReturnType的方法,用来返回方法的返回类型。这三个类都有一个getModifiers方法,返回一个整型数值,用不同的位开关描述public和static这样的修饰符使用状况。可以利用java.lang.reflect包中的Modifier类的静态方法分析getModifiers返回的整型数值。例如,可以使用Modifier类中的isPublic、isPrivate或isFinal判断方法或构造器是否是public、private或final。还可以利用Modifier.toString方法将修饰符打印出来。
下面给出的示例程序显示了如何打印一个类的全部信息:
package test;
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import java.util.Scanner;
public class ReflectionTest {
private static void printConstructors(Class cl){
System.out.println(" //Constructors");
Constructor[] constructors = cl.getDeclaredConstructors(); //返回类中声明的全部构造器
for(Constructor cx : constructors){
String modifier = Modifier.toString(cx.getModifiers()); // 返回构造器的修饰符
System.out.print(" " + modifier + " " + cx.getName() + "(");
Class[] pts = cx.getParameterTypes(); // 返回所有参数类型
StringBuilder sb = new StringBuilder();
for(int i = 0; i < pts.length; i++){
String ptype = pts[i].getTypeName();
if(i != pts.length - 1){
sb.append(ptype + ", ");
} else {
sb.append(ptype);
}
}
System.out.print(sb.toString() + ");\n");
}
}
private static void printFields(Class cl){
System.out.println(" //Fields");
Field[] fields = cl.getDeclaredFields(); // 返回类中声明的全部域
for(Field fx : fields){
String modifier = Modifier.toString(fx.getModifiers()); // 返回域的修饰符
Class type = fx.getType(); // 返回域的类型
System.out.println(" " + modifier + " " + type.getName() + " " + fx.getName() + ";");
}
}
private static void printMethods(Class cl){
System.out.println(" //Methods");
Method[] methods = cl.getDeclaredMethods(); // 返回类中声明的全部方法
for(Method mx : methods){
String modifier = Modifier.toString(mx.getModifiers()); // 返回方法的修饰符
Class ret = mx.getReturnType(); // 返回方法的返回类型
System.out.print(" " + modifier + " " + ret.getName() + " " + mx.getName() + "(");
Class[] params = mx.getParameterTypes(); // 返回方法的参数类型
StringBuilder sb = new StringBuilder();
for(int i = 0; i < params.length; i++){
String ptype = params[i].getTypeName();
if(i < params.length - 1){
sb.append(ptype + ", ");
}else {
sb.append(ptype);
}
}
System.out.print(sb.toString() + ");\n");
}
}
public static void main(String[] args) {
String className;
Scanner sc = new Scanner(System.in);
System.out.println("Please input the class name(e.g. java.util.Date):");
if(sc.hasNextLine()){
className = sc.nextLine();
try {
Class cl = Class.forName(className); // 返回类
Class supercl = cl.getSuperclass(); // 获得超类
String modifier = Modifier.toString(cl.getModifiers()); // 获得类修饰符
System.out.print(modifier + " class " + cl.getName());
if(supercl != null && supercl != Object.class){
System.out.print(" extends " + supercl.getName());
}
System.out.print("{\n");
printFields(cl);
System.out.println();
printConstructors(cl);
System.out.println();
printMethods(supercl);
System.out.println(" }");
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
}
sc.close();
}
}
结果如下: