内省(Introspector)是Java 语言对Bean类属性、事件的一种缺省处理方法。例如类 A 中有属性 name, 那我们可以通过 getName,setName 来得到其值或者设置新的值。通过 getName/setName 来访问 name 属性,这就是默认的规则。
Java 中提供了一套 API 用来访问某个属性的 getter/setter 方法,通过这些 API 可以使你不需要了解这个规则(但你最好还是要搞清楚),这些 API 存放于包 java.beans 中。
测定代码:
package com.beans;
public class User {
private int age;
private String name;
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int compute(int n) {
return 10 * n;
}
}
package com.beans;
import java.beans.BeanInfo;
import java.beans.IntrospectionException;
import java.beans.Introspector;
import java.beans.MethodDescriptor;
import java.beans.PropertyDescriptor;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import junit.framework.TestCase;
import static java.lang.System.out;
public class TestIntrospector extends TestCase {
public void testIntrospector1() {
try {
BeanInfo beanInfo = Introspector.getBeanInfo(User.class);
PropertyDescriptor[] propertyDescriptors = beanInfo.getPropertyDescriptors();
User user = new User();
for (PropertyDescriptor propertyDescriptor : propertyDescriptors) {
Method writeMethod = propertyDescriptor.getWriteMethod();
try {
if ("age".equals(propertyDescriptor.getName())) {
writeMethod.invoke(user, 18);
} else if ("name".equals(propertyDescriptor.getName())) {
writeMethod.invoke(user, "yang");
}
} catch (IllegalArgumentException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (InvocationTargetException e) {
e.printStackTrace();
}
}
out.println(user.getAge() + ", " + user.getName());
} catch (IntrospectionException e) {
e.printStackTrace();
}
}
public void testIntrospector2() {
try {
BeanInfo beanInfo = Introspector.getBeanInfo(User.class);
User user = new User();
MethodDescriptor[] methodDescriptors = beanInfo.getMethodDescriptors();
for (MethodDescriptor methodDescriptor : methodDescriptors) {
Method method = methodDescriptor.getMethod();
try {
if ("setAge".equals(methodDescriptor.getName())) {
method.invoke(user, 28);
} else if ("setName".equals(methodDescriptor.getName())) {
method.invoke(user, "yang");
}
} catch (IllegalArgumentException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (InvocationTargetException e) {
e.printStackTrace();
}
}
out.println(user.getAge() + ", " + user.getName());
} catch (IntrospectionException e) {
e.printStackTrace();
}
}
public void testIntrospector3() {
try {
User user = new User();
PropertyDescriptor propertyDescriptor = new PropertyDescriptor("age", User.class);
Method writeMethod = propertyDescriptor.getWriteMethod();
writeMethod.invoke(user, 38);
Method readMethod = propertyDescriptor.getReadMethod();
Integer age = (Integer) readMethod.invoke(user, (Object[]) null);
out.println(age);
} catch (IntrospectionException e) {
e.printStackTrace();
} catch (IllegalArgumentException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (InvocationTargetException e) {
e.printStackTrace();
}
}
}
方法testIntrospector3中的代码,我觉得是最好的。如果要遍历方法或者属性,那么上面两种也很好。