相对而言,反射比内省更容易理解一点。用一句比较白的话来概括,反射就是让你可以通过名称来得到对象 ( 类,属性,方法 ) 的技术,这种技术比内省机制使用范围更广泛。例如我们可以通过类名来生成一个类的实例;知道了方法名,就可以调用这个方法;知道了属性名就可以访问这个属性的值。 内省是 Java 语言对 Bean 类属性、事件的一种缺省处理方法。例如类 A 中有属性 name, 那我们可以通过 getName,setName 来得到其值或者设置新的值。通过 getName/setName 来访问 name 属性,这就是默认的规则。 Java 中提供了一套 API 用来访问某个属性的 getter/setter 方法,通过这些 API 可以使你不需要了解这个规则(但你最好还是要搞清楚),这些 API 存放于包 java.beans 中。
一般的做法是通过类 Introspector 来获取某个对象的 BeanInfo 信息,然后通过 BeanInfo 来获取属性的描述器( PropertyDescriptor ),通过这个属性描述器就可以获取某个属性对应的 getter/setter 方法,然后我们就可以通过反射机制来调用这些方法。下面我们来看一个例子,这个例子把某个对象的所有属性名称和值都打印出来:
Java代码
1. package
2. public class
3. private String id = null
4. private String name = null
5.
6. public
7. return
8. }
9. public void
10. this.id = id;
11. }
12.
13. public
14. return
15. }
16. public void
17. this.name = name;
18. }
19. }
20.
21. package
22. import
23. import
24. import
25. import
26. import
27. import
28. public class
29. public
30. {
31. try
32. {
33. //实例化一个Bean
34. new
35. //依据Bean产生一个相关的BeanInfo类
36. BeanInfo bInfoObject =
37. Introspector.getBeanInfo(beanObj.getClass(),beanObj.getClass().getSuperclass());
38. //定义一个用于显示的字符串
39. "";
40.
41. //开始自省
42.
43. /*
44. * BeanInfo.getMethodDescriptors()
45. * 用于获取该Bean中的所有允许公开的成员方法,以MethodDescriptor数组的形式返回
46. *
47. * MethodDescriptor类
48. * 用于记载一个成员方法的所有信息
49. * MethodDescriptor.getName()
50. * 获得该方法的方法名字
51. * MethodDescriptor.getMethod()
52. * 获得该方法的方法对象(Method类)
53. *
54. * Method类
55. * 记载一个具体的的方法的所有信息
56. * Method.getParameterTypes()
57. * 获得该方法所用到的所有参数,以Class数组的形式返回
58. *
59. * Class..getName()
60. * 获得该类型的名字
61. */
62. "内省成员方法:\n";
63. MethodDescriptor[] mDescArray = bInfoObject.getMethodDescriptors();
64. for (int i=0;i<mDescArray.length ;i++ )
65. {
66. //获得一个成员方法描述器所代表的方法的名字
67. String methodName = mDescArray[i].getName();
68.
69. new
70. //获得该方法对象
71. Method methodObj = mDescArray[i].getMethod();
72. //通过方法对象获得该方法的所有参数,以Class数组的形式返回
73. Class[] parameters = methodObj.getParameterTypes();
74. if (parameters.length>0)
75. {
76. //获得参数的类型的名字
77. 0].getName();
78. for (int j=1;j<parameters.length ;j++ )
79. {
80. ","
81. }
82. }
83. "(" + methodParams + ")\n";
84. }
85. System.out.println(output);
86.
87. /*
88. * BeanInfo.getPropertyDescriptors()
89. * 用于获取该Bean中的所有允许公开的成员属性,以PropertyDescriptor数组的形式返回
90. *
91. * PropertyDescriptor类
92. * 用于描述一个成员属性
93. *
94. * PropertyDescriptor.getName()
95. * 获得该属性的名字
96. *
97. * PropertyDescriptor.getPropertyType()
98. * 获得该属性的数据类型,以Class的形式给出
99. *
100. */
101. "内省成员属性:\n";
102. PropertyDescriptor[] mPropertyArray = bInfoObject.getPropertyDescriptors();
103. for (int i=0;i<mPropertyArray.length ;i++ )
104. {
105. String propertyName = mPropertyArray[i].getName();
106. Class propertyType = mPropertyArray[i].getPropertyType();
107. " ( " + propertyType.getName() + " )\n";
108. }
109. System.out.println(output);
110.
111.
112. /*
113. * BeanInfo.getEventSetDescriptors()
114. * 用于获取该Bean中的所有允许公开的成员事件,以EventSetDescriptor数组的形式返回
115. *
116. * EventSetDescriptor类
117. * 用于描述一个成员事件
118. *
119. * EventSetDescriptor.getName()
120. * 获得该事件的名字
121. *
122. * EventSetDescriptor.getListenerType()
123. * 获得该事件所依赖的事件监听器,以Class的形式给出
124. *
125. */
126. "内省绑定事件:\n";
127. EventSetDescriptor[] mEventArray = bInfoObject.getEventSetDescriptors();
128. for (int i=0;i<mEventArray.length ;i++ )
129. {
130. String EventName = mEventArray[i].getName();
131. Class listenerType = mEventArray[i].getListenerType();
132. "(" + listenerType.getName() + ")\n";
133. }
134. System.out.println(output);
135. "write by esonghui :");
136.
137. }
138. catch
139. {
140. "异常:"
141. }
142. }
143. public static void
144. {
145. new
146. }
147. }