package com.dhcool.introspect;
import java.beans.BeanInfo;
import java.beans.IntrospectionException;
import java.beans.Introspector;
import java.beans.PropertyDescriptor;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import com.dhcool.bean.Student;
/**
* 内省处理JavaBean有两种常用的方式:
* 1.创建出PropertyDscriptor,创建的时候要给出要获取属性的名称和具体要获取的类Class
* 得到PropertyDscriptor后就可以去调用它的方法来处理,主要还是pd.getReadMethod();获取属性值,pd.getWriteMethod();设置属性值,得到具体的方法Method
* 由Method去invoke()然后传递具体的参数(反射调用) ,就可以设置获取相应的值
*
*
* 2.用Introspector.getBeanInfo(student.getClass());去获取特定类的BeanInfo,就是Bean的包装信息
* 然后根据BeanInfo去获取 属性描述器PropertyDscriptors获取到的是一个PropertyDscriptor[]数组
* 然后迭代这个数组,获取相应属性的属性描述器 PropertyDscriptor
* 有了PropertyDscriptor就可以去获取相应的方法,之后就可以反射调用相应的方法了
*
* */
public class IntrospectTest {
public static void main(String[] args) throws Exception {
Student student = new Student();
String propertyName = "name";
setProperty(student, propertyName,"蓝");
System.out.println(getProperty(student, propertyName));
}
//获取属性值
private static Object getProperty(Object student, String propertyName)
throws IntrospectionException, IllegalAccessException,
InvocationTargetException {
/*PropertyDescriptor pd = new PropertyDescriptor(propertyName,student.getClass());
Method method = pd.getReadMethod();
return method.invoke(student);*/
//另一种处理方式
BeanInfo beanInfo = Introspector.getBeanInfo(student.getClass());
PropertyDescriptor[] pds = beanInfo.getPropertyDescriptors();
Object obj = null;
for(PropertyDescriptor pd : pds){
if(pd.getName().equals(propertyName)){
Method method = pd.getReadMethod();
obj = method.invoke(student);
}
}
return obj;
}
//设置属性值
private static Object setProperty(Object student, String propertyName, Object value)
throws IntrospectionException, IllegalAccessException,
InvocationTargetException {
//PropertyDescriptor属性描述器,用于获取属性的一些列信息,初始化的时候要给定要获取的属性名称,和要获取的类class
PropertyDescriptor pd = new PropertyDescriptor(propertyName,student.getClass());
//获取setName方法
Method methodName = pd.getWriteMethod();
//获取了这个方法之后就去调用执行这个方法。如果是静态的方法就不用传入具体的对象,如果是非静态的就要传入具体的对象
return methodName.invoke(student,value);
}
}