introspector(内省)-->javaBean的操作-->特殊的JAVA类,
JAVABEAN: 名称符合阅读的规则, getXX(), setXX() 这种类可以称之为JAVABEAN
java 类不一定可以当作JAVABEAN进行操作.. 需要看是否有没有SET与GET方法
set方法是带参数的, 将外部的值传递给内部的变量使用, get方法是返回内部变量的值
JDK中提供了对JavaBean进行操作的一些API,这套API就称为内省。如果要你自己去通过getX方法来访问私有的x,怎么做,有一定难度吧?用内省这套api操作JavaBean比用普通类的方式更方便。
首先看一个例子
public class IntroSpectorTest {
/**
* @param args
*/
public static void main(String[] args) throws Exception {
// TODO Auto-generated method stub
ReflectPoint pt1 = new ReflectPoint(3,5);
String propertyName = "x"; //在ReflectPoint类里有一个方法叫做getX
//"x"-->"X"-->"getX"-->MethodGetX-->
//根据 PropertyDescriptor 获取到属性的set 以及 get 方法,返回是Object类型, 这里是被抽出来的方法
Object retVal = getProperty(pt1, propertyName); //此方法相当于我们用类的实例对象get到属性的方法
System.out.println(retVal); // 原来ReflectPoint里x 的值为3 获取上来, 所以值是3
Object value = 7; //我们要将进赋值给x
setProperties(pt1, propertyName, value); // 这个方法相当于set属性, set 进去后打印的值其实是null.
// 因为他只做赋值操作,不做获取值的操作.. 根据经验来断定,这里绝对是null
System.out.println( getProperty(pt1, propertyName)); //这时候再获取一遍 值为7, 因为赋值过了
}
private static void setProperties(Object pt1, String propertyName,
Object value) throws IntrospectionException, IllegalAccessException, InvocationTargetException {
PropertyDescriptor pd2 = new PropertyDescriptor(propertyName,pt1.getClass());
// 先用PropertyDescriptor获取到成员的属性方法, 接着再作用于对象,是通过pt1.class获取来的
Method methodSetX = pd2.getWriteMethod(); //获取对象的成员赋值写入的方法.. 其实这步应该加上变量的字节码会
//让代码变得更严谨.. 目测getWriteMethod 内部已经封装好了
//赋值变量的字节码--obejct.class, 此方法与Field一样
//不用是的Field是变量的方法, 而Propertry 故名思意: 参数
methodSetX.invoke(pt1,value); //执行赋值操作, 作用pt1对象
}
private static Object getProperty(Object pt1, String propertyName)
throws IntrospectionException, IllegalAccessException, InvocationTargetException {
PropertyDescriptor pd = new PropertyDescriptor(propertyName,pt1.getClass());
//通过名字先得到JAVABEAN里的成员,作用于PT1这个对象上
Method methodGetX = pd.getReadMethod(); // 然后获取到成员的get 方法
return methodGetX;
}
}
BeanInfo 的使用
IntroSpector.getBeanInfo(); 这个方法相当于得到一个BeanInfo对象, 可以把普通的JAVA类当成封装好的JAVABEAN来看,返回结果
BeanInfo beanInfo = Introspector.getBeanInfo(pt1.getClass()); //将pt1当成JAVABEAN来看
PropertyDescriptor[] pds = beanInfo.getPropertyDescriptors(); //返回来pt1里所有的属性,不能只返回一个
//然后迭代它. 接着判断属性的名字即可
Object retVal = null;
for(PropertyDescriptor pd : pds){
if(pd.getName().equals(propertyName)) //比如说 正要操作的是"x"这个属性, 那么判断到x的时候执行
{
Method methodGetX = pd.getReadMethod(); //这个属性有Read 和 Writer 2个, 这里我们要做读取
//所以是Read
retVal = methodGetX.invoke(pt1);//get方法不需要值, 直接作用于对象实例即可 获取到的值赋值给retVal
break;
}
}
return retVal;
BeanUtil的使用
BeanUtil 是一个JAR包(这句省略).. 从appache上去下载common-BeanUtil工具包,
System.out.println(BeanUtils.getProperty(pt1,"x"));//由于BeanUtil 里的方法也是引用别人的包, 所以这里还需要导入一个日志包
System.out.println(BeanUtils.getProperty(pt1, "x").getClass().getName()); // 获取上来竟然是字符串类型, 不可思议
BeanUtils.setProperty(pt1, "x", "9"); //细节: 这里传的是一个字符串 , 其实类里是一个int类型,
//由于BeanUtil会将所有的值都转成字符串操作
System.out.println(pt1.getX()); // 获取回来, 答案是 9;
PropertyUtil 的使用
类似于BeanUtil , 不同的是Property里的getProperty 方法里传的是参数原本类型, 而BeanUtil传的是字符串