Java中的反射
一,反射是什么
Java反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法;对于任意一个对象, 都能够调用它的任意一个方法和属性;这种动态获取的信息以及动态调用对象的方法的功能称为Java语言的反射机制。
“程序运行时,允许改变程序结构或变量类型,这种语言称为动态语言”。从这个观点看,Perl,Python,Ruby是动态语言,C++,Java,C# 不是动态语言。但是Java有着一个非常突出的动态相关机制:Reflection,用在Java身上指的是我们可以于运行时加载、探知、使用编译期间完 全未知的classes。换句话说,Java程序可以加载一个运行时才得知名称的class,获悉其完整构造(但不包括methods定义),并生成其对 象实体、或对其fields设值、或唤起其methods。
二, 反射能干什么
• 在运行时判断任意一个对象所属的类
• 在运行时构造任意一个类的对象
• 在运行时判断任意一个类所具有的成员变量和方法
• 在运行时调用任意一个对象的方法
三,包含类型信息的类-Class
1,如何获得Class对象
在程序运行时,系统始终为所有的对象维护一个被称为运行时的类型标识,它保存着每个对象所属的类足迹,虚拟机利用运行时信息选择相应的方法执行。保存这些信息的类被称为Class,有三种方法获得Class对象
a,使用Object.getClass方法,该方法返回一个Class类型的实例。
b,使用静态方法forName获得类名对应的Class对象,需要注意的是该方法会抛出一个异常,需要对其进行捕获。
1 String className = "java.util.Date"; 2 Class cl = Class.forName(className);
1 Class cl1 = Date.class; 2 Class cl2 = int.class; 3 Class cl3 = Double[].class;
四, 利用反射分析类
1,核心类概述
java.lang.reflect中有三个类Field,Method和Constructor分别用于描述类的域,方法和构造器。
三个类都有getName方法返回条目的名称,都有getModifiers方法返回一个整型数值表示public和static修饰符的使用状况。对于返回的整型值,可以调用java.lang.reflect.Modifier类的静态方法,比如isPublic,isPrivate或isFinal等进行判断,还可以使用Modifier.toString将修饰符打印出来。
Field类有一个getType方法用来返回描述域所属类型的Class对象。
Method具有能够报告参数和返回类型的方法。
Constructor具有能够报告参数类型的方法。
2,使用步骤
a,使用第三点中的任意一种方法获得Class对象。
b,通过Class对象调用getDeclareFields获得域数组,Method和Constructor与之类似。
c,遍历该数组,解析出修饰符,参数类型,返回类型等信息。
3,示例
1 import java.lang.*; 2 import java.lang.reflect.*; 3 import java.util.*; 4 5 public class test 6 { 7 public static void main(String[] args) 8 { 9 String className = "java.lang.Double"; 10 /* 11 if(args.length == 0) 12 { 13 Scanner in = new Scanner(System.in); 14 className = in.next(); 15 } 16 else 17 { 18 className = args[0]; } 19 */ 20 try 21 { 22 Class cl = Class.forName(className); 23 String modifiers = Modifier.toString(cl.getModifiers()); 24 System.out.printf(modifiers); 25 System.out.printf(" class " + className); 26 System.out.println(); 27 System.out.println("{"); 28 printFields(cl); 29 System.out.println(); 30 printConstructors(cl); 31 System.out.println(); 32 printMethods(cl); 33 System.out.println(); 34 System.out.println("}"); 35 } 36 catch(ClassNotFoundException e) 37 { 38 e.printStackTrace(); 39 } 40 } 41 public static void printFields(Class cl) 42 { 43 Field[] fields = cl.getDeclaredFields(); 44 for(Field field: fields) 45 { 46 String modifiers = Modifier.toString(field.getModifiers()); 47 System.out.println(" " + modifiers + " " + 48 (field.getType()).getName() + " " + field.getName() + ";"); 49 } 50 } 51 public static void printMethods(Class cl) 52 { 53 Method[] methods = cl.getDeclaredMethods(); 54 for(Method method: methods) 55 { 56 String modifiers = Modifier.toString(method.getModifiers()); 57 System.out.printf(" " + modifiers + " " + method.getReturnType().getName() 58 + " " + method.getName() + "("); 59 Class[] paraTypes = method.getParameterTypes(); 60 for(int i = 0; i < paraTypes.length; ++i) 61 { 62 if(i > 0) 63 System.out.printf(", "); 64 System.out.printf(paraTypes[i].getName()); 65 } 66 System.out.println(");"); 67 //System.out.println(method.toString()); 68 } 69 } 70 public static void printConstructors(Class cl) 71 { 72 Constructor[] constructors = cl.getDeclaredConstructors(); 73 for(Constructor constructor: constructors) 74 { 75 String modifiers = Modifier.toString(constructor.getModifiers()); 76 System.out.printf(" " + modifiers + " " + constructor.getName() 77 + " " + "("); 78 Class[] paraTypes = constructor.getParameterTypes(); 79 for(int i = 0; i < paraTypes.length; ++i) 80 { 81 if(i > 0) 82 System.out.printf(", "); 83 System.out.printf(paraTypes[i].getName()); 84 } 85 System.out.println(");"); 86 } 87 } 88 }
输出结果为:
1 public final class java.lang.Double 2 { 3 public static final double POSITIVE_INFINITY; 4 public static final double NEGATIVE_INFINITY; 5 public static final double NaN; 6 public static final double MAX_VALUE; 7 public static final double MIN_NORMAL; 8 public static final double MIN_VALUE; 9 public static final int MAX_EXPONENT; 10 public static final int MIN_EXPONENT; 11 public static final int SIZE; 12 public static final int BYTES; 13 public static final java.lang.Class TYPE; 14 private final double value; 15 private static final long serialVersionUID; 16 17 public java.lang.Double (double); 18 public java.lang.Double (java.lang.String); 19 20 public boolean equals(java.lang.Object); 21 public static java.lang.String toString(double); 22 public java.lang.String toString(); 23 public int hashCode(); 24 public static int hashCode(double); 25 public static double min(double, double); 26 public static double max(double, double); 27 public static native long doubleToRawLongBits(double); 28 public static long doubleToLongBits(double); 29 public static native double longBitsToDouble(long); 30 public volatile int compareTo(java.lang.Object); 31 public int compareTo(java.lang.Double); 32 public byte byteValue(); 33 public short shortValue(); 34 public int intValue(); 35 public long longValue(); 36 public float floatValue(); 37 public double doubleValue(); 38 public static java.lang.Double valueOf(java.lang.String); 39 public static java.lang.Double valueOf(double); 40 public static java.lang.String toHexString(double); 41 public static int compare(double, double); 42 public static boolean isNaN(double); 43 public boolean isNaN(); 44 public static boolean isInfinite(double); 45 public boolean isInfinite(); 46 public static boolean isFinite(double); 47 public static double sum(double, double); 48 public static double parseDouble(java.lang.String); 49 50 }