能够分析类的功能的程序称为反射程序,反射机制的功能相当强大,几个基本的应用是:
- 在运行时分析各种类的功能;
- 在运行时对对象进行分析...
- 实现繁星数组操作的代码
- 使用Method方法就像使用C++中的函数指针一样;
1. Class 类:
当程序运行时,Java运行时系统维持一份包含每个对象运行时类型标记的信息。这个信息标记了每个对象所属的类型。运行时类型
信息为虚拟机找到正确的函数提供了依据。但这个信息可以通过类的getClass方法得到!
1 public class TestReflection
2 {
3 public static void main(String[] args)
4 {
5 Person per = new Person("Bruce Lee");
6 System.out.println(per.getClass().getName()+" "+per.getName());
7 }
8 }
9
10 class Person
11 {
12 public Person(String aName)
13 {
14 name = aName;
15 }
16
17 public String getName()
18 {
19 return name;
20 }
21
22 private String name;
23 }
内存中每个Class对象只有唯一的一个:
if(e.getClass() == Employee.class)
这里用==号,而不是equals.
Class对象的另外一个重要的用途是在线创建对象:
Class的forName方法和newInstance方法,以及Java的class文件只有在执行时才装载的特性,这几点
位Java在运行时动态执行“未来的”类提供了重要的基础,借助它,你可以方便的实现构件化组装式的应用架构。
可以按照下面这种方式来实现:
1) 主程序中可以不知道构建的具体实现类,而是依据一个配置文件获得构建的具体实现类名;
2) 主程序执行时,从配置文件中读取构建的具体类名,然后用forName的方法和newInstance方法创建类的对象。
2. 使用反射机制来分析类的功能:
1 import java.util.*;
2 import java.lang.reflect.*;
3
4 public class ReflectionTest
5 {
6 public static void main(String[] args)
7 {
8 // read class name from command line args or user input
9 String name;
10 if(args.length > 0)
11 name = args[0];
12 else
13 {
14 Scanner in = new Scanner(System.in);
15 System.out.println("Enter the class name(e.g. java.util.Date): ");
16 name = in.next();
17 }
18
19 try
20 {
21 //print class name and superclass name
22 Class cl = Class.forName(name);
23 Class supercl = cl.getSuperclass();
24 String modifiers = Modifier.toString(cl.getModifiers());
25 if(modifiers.length() > 0)
26 System.out.print("class "+name);
27 if(supercl != null && supercl != Object.class)
28 System.out.print(" extends "+supercl.getName());
29
30 System.out.print("\n{\n");
31 printConstructors(cl);
32 System.out.println();
33 printMethods(cl);
34 System.out.println();
35 printFields(cl);
36 System.out.println();
37 System.out.println("}");
38 }
39 catch(ClassNotFoundException e)
40 {
41 e.printStackTrace();
42 }
43 System.exit(0);
44 }
45
46 /**
47 * Print all constructors of a class
48 * @param cl a class
49 */
50 public static void printConstructors(Class cl)
51 {
52 Constructor[] constructors = cl.getDeclaredConstructors();
53
54 for(Constructor c: constructors)
55 {
56 String name = c.getName();
57 System.out.print(" ");
58 String modifiers = Modifier.toString(c.getModifiers());
59 if(modifiers.length() > 0) System.out.print(modifiers+" ");
60 System.out.print(name + "(");
61
62 //print parameter types
63 Class[] paraTypes = c.getParameterTypes();
64 for(int j = 0; j < paraTypes.length; j++)
65 {
66 if(j > 0) System.out.print(", ");
67 System.out.print(paraTypes[j].getName());
68 }
69 System.out.println(");");
70 }
71 }
72
73 /**
74 * Prints all methods of a class
75 * @param cl a class
76 */
77 public static void printMethods(Class cl)
78 {
79 Method[] methods = cl.getDeclaredMethods();
80
81 for(Method m : methods)
82 {
83 Class retType = m.getReturnType();
84 String name = m.getName();
85
86 System.out.print(" ");
87 //print modifies, return type and method name
88 String modifiers = Modifier.toString(m.getModifiers());
89 if(modifiers.length() > 0)
90 System.out.print(modifiers + " ");
91 System.out.print(retType + " " + name + "(");
92
93 //print paramrter types
94 Class[] paramTypes = m.getParameterTypes();
95 for(int j = 0; j < paramTypes.length; j++)
96 {
97 if(j > 0) System.out.print(", ");
98 System.out.print(paramTypes[j].getName());
99 }
100 System.out.println(");");
101 }
102 }
103
104 /**
105 * Prints all fields of a class
106 * @param cl a class
107 */
108 public static void printFields(Class cl)
109 {
110 Field[] fields = cl.getDeclaredFields();
111
112 for(Field f : fields)
113 {
114 Class type = f.getType();
115 String name = f.getName();
116 System.out.print(" ");
117 String modifiers = Modifier.toString(f.getModifiers());
118 if(modifiers.length() > 0)
119 System.out.print(modifiers + " ");
120 System.out.println(type.getName() + " " + name + ";");
121 }
122 }
123
124 }
上面这段打印一个类的所有信息:
1 Enter the class name(e.g. java.util.Date):
2 class java.util.Date
3 {
4 public java.util.Date();
5 public java.util.Date(long);
6 public java.util.Date(int, int, int, int, int);
7 public java.util.Date(int, int, int, int, int, int);
8 public java.util.Date(java.lang.String);
9 public java.util.Date(int, int, int);
10
11 public long getTime();
12 public void setTime(long);
13 public int getHours();
14 public int getMinutes();
15 public int getMonth();
16 public int getSeconds();
17 public int getYear();
18 public static long UTC(int, int, int, int, int, int);
19 private static final class java.lang.StringBuilder convertToAbbr(java.lang.StringBuilder, java.lang.String);
20 private final class sun.util.calendar.BaseCalendar$Date getCalendarDate();
21 private static final class sun.util.calendar.BaseCalendar getCalendarSystem(sun.util.calendar.BaseCalendar$Date);
22 private static final class sun.util.calendar.BaseCalendar getCalendarSystem(int);
23 private static final class sun.util.calendar.BaseCalendar getCalendarSystem(long);
24 public int getDay();
25 private static final synchronized class sun.util.calendar.BaseCalendar getJulianCalendar();
26 static final long getMillisOf(java.util.Date);
27 private final long getTimeImpl();
28 public int getTimezoneOffset();
29 public void setDate(int);
30 public void setHours(int);
31 public void setMinutes(int);
32 public void setMonth(int);
33 public void setSeconds(int);
34 public void setYear(int);
35 public class java.lang.String toGMTString();
36 public class java.time.Instant toInstant();
37 public class java.lang.String toLocaleString();
38 public int getDate();
39 public static class java.util.Date from(java.time.Instant);
40 public boolean equals(java.lang.Object);
41 public class java.lang.String toString();
42 public int hashCode();
43 public class java.lang.Object clone();
44 public int compareTo(java.util.Date);
45 public volatile int compareTo(java.lang.Object);
46 private void readObject(java.io.ObjectInputStream);
47 private void writeObject(java.io.ObjectOutputStream);
48 private final class sun.util.calendar.BaseCalendar$Date normalize();
49 private final class sun.util.calendar.BaseCalendar$Date normalize(sun.util.calendar.BaseCalendar$Date);
50 public static long parse(java.lang.String);
51 public boolean after(java.util.Date);
52 public boolean before(java.util.Date);
53
54 private static final sun.util.calendar.BaseCalendar gcal;
55 private static sun.util.calendar.BaseCalendar jcal;
56 private transient long fastTime;
57 private transient sun.util.calendar.BaseCalendar$Date cdate;
58 private static int defaultCenturyStart;
59 private static final long serialVersionUID;
60 private static final [Ljava.lang.String; wtb;
61 private static final [I ttb;
62
63 }
2. 利用反射机制来进行运行时的对象分析:
在程序初始化时就已经设置好的数据域是很好观察的,但反射机制可以观察运行时的数据域信息。
Java面向对象程序设计--Java反射机制