具有能够分析类能力的程序被称为反射,使用反射库可以编写能够动态操纵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:
1 import java.lang.reflect.Constructor; 2 import java.lang.reflect.Field; 3 import java.lang.reflect.Method; 4 import java.lang.reflect.Modifier; 5 import java.util.Scanner; 6 /** 7 * waring : params part will be changed if param was array 8 * ex. byte[] --> [B 9 */ 10 11 public class ReflectionTest { 12 public static void main(String[] args) { 13 String name; 14 if(args.length>0){ 15 name=args[0]; 16 }else{ 17 Scanner in =new Scanner(System.in); 18 System.out.println("Enter class name (e.g. java.util.Date):"); 19 name=in.next(); 20 System.out.println("Input:"+name); 21 } 22 try { 23 Class cl=Class.forName(name); 24 Class superCl=cl.getSuperclass(); //super one 25 Class[] interfacesCl=cl.getInterfaces(); 26 String modifiers=Modifier.toString(cl.getModifiers()); 27 if(modifiers.length()>0){ 28 System.out.print(modifiers+" "); 29 } 30 System.out.print("class "+name); 31 32 if(superCl!=null && superCl !=Object.class){ 33 System.out.print(" extends "+superCl.getName()); 34 } 35 for(int i=0;i<interfacesCl.length;i++){ 36 if(i==0){ 37 System.out.print(" implements "); 38 } 39 if(i>0){ 40 System.out.print(","); 41 } 42 System.out.print(interfacesCl[i].getName()); 43 } 44 System.out.print("\n{\n"); 45 printConstructors(cl); 46 System.out.println(); 47 printMethod(cl); 48 System.out.println(); 49 pritField(cl); 50 System.out.println("}"); 51 } catch (ClassNotFoundException e) { 52 e.printStackTrace(); 53 } 54 } 55 /** 56 * Prints all constructors of a class 57 * @param cl 58 */ 59 public static void printConstructors(Class cl){ 60 Constructor[] constructors=cl.getConstructors(); 61 for(Constructor c:constructors){ 62 String name=c.getName(); 63 System.out.print(" "); 64 String modifiers=Modifier.toString(c.getModifiers()); 65 if(modifiers.length()>0){ 66 System.out.print(modifiers+" "); 67 } 68 System.out.print(name+"("); 69 70 Class[] paramTypes=c.getParameterTypes(); 71 for(int i=0;i<paramTypes.length;i++){ 72 if(i>0){ 73 System.out.print(","); 74 } 75 System.out.print(paramTypes[i].getName()); 76 } 77 System.out.println(");"); 78 } 79 } 80 81 /** 82 * Prints all method of a class 83 * @param cl 84 */ 85 public static void printMethod(Class cl){ 86 Method[] methods=cl.getMethods(); 87 for(Method m:methods){ 88 String name =m.getName(); 89 System.out.print(" "); 90 String modifiers=Modifier.toString(m.getModifiers()); 91 if(modifiers.length()>0){ 92 System.out.print(modifiers+" "); 93 } 94 System.out.print(name+"("); 95 Class[] params=m.getParameterTypes(); 96 for(int i=0;i<params.length;i++){ 97 if(i>0){ 98 System.out.print(","); 99 } 100 System.out.print(params[i].getName()); 101 } 102 System.out.println(");"); 103 } 104 } 105 106 public static void pritField(Class cl){ 107 Field[] fields=cl.getFields(); 108 for(Field field:fields){ 109 String name=field.getName(); 110 System.out.print(" "); 111 String str_fields=Modifier.toString(field.getModifiers()); 112 if(str_fields.length()>0){ 113 System.out.print(str_fields+" "); 114 } 115 System.out.println(name+";"); 116 } 117 } 118 }
Result:
这里要注意有一点坑坑的,就是如果你的参数是个数组的话参数打印那里会出现奇怪的表达:
例如: byte[] --> [B