转自:http://yangzhibin-java.javaeye.com/
相对而言,反射比内省更容易理解一点。用一句比较白的话来概括,反射就是让你可以通过名称来得到对象 ( 类,属性,方法 ) 的技术,这种技术比内省机制使用范围更广泛。例如我们可以通过类名来生成一个类的实例;知道了方法名,就可以调用这个方法;知道了属性名就可以访问这个属性的值。 内省是 Java 语言对 Bean 类属性、事件的一种缺省处理方法。例如类 A 中有属性 name, 那我们可以通过 getName,setName 来得到其值或者设置新的值。通过 getName/setName 来访问 name 属性,这就是默认的规则。 Java 中提供了一套 API 用来访问某个属性的 getter/setter 方法,通过这些 API 可以使你不需要了解这个规则(但你最好还是要搞清楚),这些 API 存放于包 java.beans 中。
一般的做法是通过类 Introspector 来获取某个对象的 BeanInfo 信息,然后通过 BeanInfo 来获取属性的描述器( PropertyDescriptor ),通过这个属性描述器就可以获取某个属性对应的 getter/setter 方法,然后我们就可以通过反射机制来调用这些方法。下面我们来看一个例子,这个例子把某个对象的所有属性名称和值都打印出来:
1
package
MyTest;
2 public class bean {
3 private String id = null ;
4 private String name = null ;
5
6 public String getId() {
7 return id;
8 }
9 public void setId(String id) {
10 this .id = id;
11 }
12
13 public String getName() {
14 return name;
15 }
16 public void setName(String name) {
17 this .name = name;
18 }
19 }
20
21 package MyTest;
22 import java.beans.BeanInfo;
23 import java.beans.EventSetDescriptor;
24 import java.beans.Introspector;
25 import java.beans.MethodDescriptor;
26 import java.beans.PropertyDescriptor;
27 import java.lang.reflect.Method;
28 public class myBeanIntrospector {
29 public myBeanIntrospector()
30 {
31 try
32 {
33 // 实例化一个Bean
34 bean beanObj = new bean();
35 // 依据Bean产生一个相关的BeanInfo类
36 BeanInfo bInfoObject =
37 Introspector.getBeanInfo(beanObj.getClass(),beanObj.getClass().getSuperclass());
38 // 定义一个用于显示的字符串
39 String output = "" ;
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 output = " 内省成员方法:\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 String methodParams = new String();
70 // 获得该方法对象
71 Method methodObj = mDescArray[i].getMethod();
72 // 通过方法对象获得该方法的所有参数,以Class数组的形式返回
73 Class[] parameters = methodObj.getParameterTypes();
74 if (parameters.length > 0 )
75 {
76 // 获得参数的类型的名字
77 methodParams = parameters[ 0 ].getName();
78 for ( int j = 1 ;j < parameters.length ;j ++ )
79 {
80 methodParams = methodParams + " , " + parameters[j].getName();
81 }
82 }
83 output += methodName + " ( " + 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 output = " 内省成员属性:\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 output += propertyName + " ( " + 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 output = " 内省绑定事件:\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 output += EventName + " ( " + listenerType.getName() + " )\n " ;
133 }
134 System.out.println(output);
135 System.out.println( " write by esonghui : " );
136
137 }
138 catch (Exception e)
139 {
140 System.out.println( " 异常: " + e);
141 }
142 }
143 public static void main(String[] args)
144 {
145 new myBeanIntrospector();
146 }
147 }
2 public class bean {
3 private String id = null ;
4 private String name = null ;
5
6 public String getId() {
7 return id;
8 }
9 public void setId(String id) {
10 this .id = id;
11 }
12
13 public String getName() {
14 return name;
15 }
16 public void setName(String name) {
17 this .name = name;
18 }
19 }
20
21 package MyTest;
22 import java.beans.BeanInfo;
23 import java.beans.EventSetDescriptor;
24 import java.beans.Introspector;
25 import java.beans.MethodDescriptor;
26 import java.beans.PropertyDescriptor;
27 import java.lang.reflect.Method;
28 public class myBeanIntrospector {
29 public myBeanIntrospector()
30 {
31 try
32 {
33 // 实例化一个Bean
34 bean beanObj = new bean();
35 // 依据Bean产生一个相关的BeanInfo类
36 BeanInfo bInfoObject =
37 Introspector.getBeanInfo(beanObj.getClass(),beanObj.getClass().getSuperclass());
38 // 定义一个用于显示的字符串
39 String output = "" ;
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 output = " 内省成员方法:\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 String methodParams = new String();
70 // 获得该方法对象
71 Method methodObj = mDescArray[i].getMethod();
72 // 通过方法对象获得该方法的所有参数,以Class数组的形式返回
73 Class[] parameters = methodObj.getParameterTypes();
74 if (parameters.length > 0 )
75 {
76 // 获得参数的类型的名字
77 methodParams = parameters[ 0 ].getName();
78 for ( int j = 1 ;j < parameters.length ;j ++ )
79 {
80 methodParams = methodParams + " , " + parameters[j].getName();
81 }
82 }
83 output += methodName + " ( " + 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 output = " 内省成员属性:\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 output += propertyName + " ( " + 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 output = " 内省绑定事件:\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 output += EventName + " ( " + listenerType.getName() + " )\n " ;
133 }
134 System.out.println(output);
135 System.out.println( " write by esonghui : " );
136
137 }
138 catch (Exception e)
139 {
140 System.out.println( " 异常: " + e);
141 }
142 }
143 public static void main(String[] args)
144 {
145 new myBeanIntrospector();
146 }
147 }