内省(Introspector) 是Java 语言对 JavaBean 类属性、事件的一种处理方法。javaBean的成员变量,如果要成为属性,那么需要拥有getter/setter方法。在平常使用中,如果需要获取或者设置属性,我们只需要调用相应属性的setter/getter方法即可。其实,除此之外,java提供了内省的方式获取或设置属性。
假设有两个类,一个是用户信息类,另一个是地址类,我们需要使用内省的方式设置和获取属性值。
public class UserInfo {
private String userName;
private int age;
private Addr addr;
public String getUserName() {
return userName;
}
public void setUserName(String userName) {
this.userName = userName;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public Addr getAddr() {
return addr;
}
public void setAddr(Addr addr) {
this.addr = addr;
}
}
public class Addr {
private String name;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
下面将介绍两种实现内省的方法,一种是通过jdk库,另一个是通过apache的beanUtils工具包。
JDK内省类库
public class JavaSdkMain {
public static void main(String[] args) throws Exception {
UserInfo userInfo = new UserInfo();
Addr addr = new Addr();
addr.setName("china");
// 设置属性
setProperty(userInfo, "userName", "hugo");
setProperty(userInfo, "age", 21);
setProperty(userInfo, "addr", addr);
// 读取属性
System.out.println(getProperty(userInfo, "userName"));
System.out.println(getProperty(userInfo, "age"));
Addr retrievedAddr = (Addr) getProperty(userInfo, "addr");
System.out.println(retrievedAddr);
}
/**
* 通过内省方式设置bean的属性
*
* @param target 目标类
* @param propertyName 属性名
* @param value 参数
* @throws Exception
*/
private static void setProperty(Object target, String propertyName, Object value) throws Exception {
PropertyDescriptor proDescriptor = new PropertyDescriptor(propertyName, target.getClass());
Method writer = proDescriptor.getWriteMethod();
writer.invoke(target, value);
}
/**
* 通过内省方式获取bean的属性
*
* @param target 目标类
* @param propertyName 属性名
* @throws Exception
*/
private static Object getProperty(Object target, String propertyName) throws Exception {
PropertyDescriptor proDescriptor = new PropertyDescriptor(propertyName, target.getClass());
Method readMethod = proDescriptor.getReadMethod();
return readMethod.invoke(target);
}
}
BeanUtils工具包
public class BeanUtilsMain {
public static void main(String[] args) throws Exception {
UserInfo userInfo = new UserInfo();
Addr addr = new Addr();
addr.setName("china");
// 设置属性
setProperty(userInfo, "userName", "hugo");
setProperty(userInfo, "age", 21);
setProperty(userInfo, "addr", addr);
// 读取属性
System.out.println(getProperty(userInfo, "userName"));
System.out.println(getProperty(userInfo, "age"));
Addr retrievedAddr = (Addr) getProperty(userInfo, "addr");
System.out.println(retrievedAddr);
}
/**
* 通过内省方式设置bean的属性
*
* @param target 目标类
* @param propertyName 属性名
* @param value 参数
* @throws Exception
*/
private static void setProperty(Object target, String propertyName, Object value) throws NoSuchMethodException, InvocationTargetException, IllegalAccessException {
PropertyUtils.setProperty(target, propertyName, value);
}
/**
* 通过内省方式获取bean的属性
*
* @param target 目标类
* @param propertyName 属性名
* @throws Exception
*/
private static Object getProperty(Object target, String propertyName) throws IllegalAccessException,
NoSuchMethodException, InvocationTargetException {
return PropertyUtils.getProperty(target, propertyName);
}
}