具有能够分析类能力的程序被称为反射,使用反射库可以编写能够动态操纵Java代码的程序。
一、开始
背景:Java运行时系统始终对所有对象维护一个被称为Runtime的类型标识,然后这货save着每个对象所属类的足迹,虚拟机利用运行时信息选择相应方法执行。保存这些信息的类为Class,取得Class的实例化对象就可以进行下一步的操作了:
- Class类:
- 取得Class类对象的三种方法:
- getClass():
- Hehe e; Class cl=e.getClass();
- forName(String name):
- String className="java.util.Date"; Class cl=Class.forName(className);
- T.class:
- Class cl1=Date.class;
二、使用反射分析类
发射机制的最重要内容--检测类的结构。
Java.lang.reflect为反射包,里面有以下四个类:
Fiend
属性
getDeclareFields() & getFields()
Method
方法
getDeclareMethods() & getMethods()
Constructor
构造
getDeclareConstructor() & getConstructor()
Modifier
修饰
getModifiers()
对于Fiend , Method , Constructor 都有一个方法 getName() ,可以用来取得属性|方法|构造名,
然后上面每个类最后的两个方法,有Declare的那个是取得全部域、方法、构造器,
没有Declare的那个是取得public型的域、方法、构造器。
对于Modifier,有方法getModifiers(),用来取得一个int型值,放入Modifier.toString(int a)中就能得到对应的修饰法。(即public,private等)。
p.s.对于Modifier的getModifiers()取得int后,还有许多判断方法,都是is开头的.
Code:
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import java.util.Scanner;
/**
* waring : params part will be changed if param was array
* ex. byte[] --> [B
*/ public class ReflectionTest {
public static void main(String[] args) {
String name;
if(args.length>0){
name=args[0];
}else{
Scanner in =new Scanner(System.in);
System.out.println("Enter class name (e.g. java.util.Date):");
name=in.next();
System.out.println("Input:"+name);
}
try {
Class cl=Class.forName(name);
Class superCl=cl.getSuperclass(); //super one
Class[] interfacesCl=cl.getInterfaces();
String modifiers=Modifier.toString(cl.getModifiers());
if(modifiers.length()>0){
System.out.print(modifiers+" ");
}
System.out.print("class "+name); if(superCl!=null && superCl !=Object.class){
System.out.print(" extends "+superCl.getName());
}
for(int i=0;i<interfacesCl.length;i++){
if(i==0){
System.out.print(" implements ");
}
if(i>0){
System.out.print(",");
}
System.out.print(interfacesCl[i].getName());
}
System.out.print("\n{\n");
printConstructors(cl);
System.out.println();
printMethod(cl);
System.out.println();
pritField(cl);
System.out.println("}");
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
}
/**
* Prints all constructors of a class
* @param cl
*/
public static void printConstructors(Class cl){
Constructor[] constructors=cl.getConstructors();
for(Constructor c:constructors){
String name=c.getName();
System.out.print(" ");
String modifiers=Modifier.toString(c.getModifiers());
if(modifiers.length()>0){
System.out.print(modifiers+" ");
}
System.out.print(name+"("); Class[] paramTypes=c.getParameterTypes();
for(int i=0;i<paramTypes.length;i++){
if(i>0){
System.out.print(",");
}
System.out.print(paramTypes[i].getName());
}
System.out.println(");");
}
} /**
* Prints all method of a class
* @param cl
*/
public static void printMethod(Class cl){
Method[] methods=cl.getMethods();
for(Method m:methods){
String name =m.getName();
System.out.print(" ");
String modifiers=Modifier.toString(m.getModifiers());
if(modifiers.length()>0){
System.out.print(modifiers+" ");
}
System.out.print(name+"(");
Class[] params=m.getParameterTypes();
for(int i=0;i<params.length;i++){
if(i>0){
System.out.print(",");
}
System.out.print(params[i].getName());
}
System.out.println(");");
}
} public static void pritField(Class cl){
Field[] fields=cl.getFields();
for(Field field:fields){
String name=field.getName();
System.out.print(" ");
String str_fields=Modifier.toString(field.getModifiers());
if(str_fields.length()>0){
System.out.print(str_fields+" ");
}
System.out.println(name+";");
}
}
}
Result:
这里要注意有一点坑坑的,就是如果你的参数是个数组的话参数打印那里会出现奇怪的表达:
例如: byte[] --> [B