/**
* 1,IntroSpector内省类-->javaBean(BeanInfo)类: 特殊的Java类
*
* 如果要在两个模块之间传递信息,可以将这些信息封装到一个JavaBean中,这种JavaBean的实例对象通常称之为 值对象(Value-Object,简称VO.
* 这些信息在类中用私有字段来存储,如果读取或者设置这些字段的值,则需要通过一些方法来访问.
*
* JavaBean的属性名称是根据setter和getter方法来确定的,而不是根据其中的成员变量.如果方法名为setId,中文意思即为设置id,至于把它存到哪个变量上面,不用管!
* 去掉set/get前缀,剩余部分就是属性名:
*
* 属性名的动态调整:
*Age-->如果第二个字母是小的,则把第一个字母变成小的-->age
*gettime-->time
*setTime-->time
*getCPU-->CPU
*
* 一个符合javaBean特点的类,当做javaBean来使用的额外好处:
* 在JavaEE开发中,经常要用到javaBean.很多环境就要去按JavaBean方式进行操作;
* jdk中提供了对JavaBean进行操作的一些API,这套API就称为内省.内省API有什么好处,:
* 如果你要自己去通过getX方法来访问私有的x,有一定的难度!
* 如果用内省这套API操作JavaBean比用普通类方式更方便.
*
*/
class Person{
private int x;
public int getAge(){
return x;
}
//javabean的属性,有set方法而来,此处属性为age;
public void setAge(int age) {
this.x=age;
}
}
/**
* 演示用Eclipse将读取属性和设置属性的流水账代码分别抽取成方法:
* 只要调用这个方法,并给方法传递 对象/属性名/和设置值,它就能完成属性的修改功能;
* 得到定义PropertyDescriptor(类名称,对象Java类)BeanInfo的时候,最好采用 obj.getClass()方式,而不要采用 类名.class方式,这样程序更普遍;
*/
public class IntroSpectorTest {
public static void main(String[] args)throws Exception{
ReflectPoint pt1=new ReflectPoint(3,5);
String propertyName = "x";
//"x"-->"X"-->"getX"-->MethodGetX-->
//调用PropertyDecripetor(属性名称,对象Java类) 类的getReadMethod()和getWriteMethod()方法来获得MethodJava类,再invoke到原来的对象和参数
Object retVal = getProperty(pt1, propertyName);//getReaderMethod重构方法
System.out.println(retVal);//3
Object value = 7;
setProperties(pt1, propertyName, value);//getWriteMethod重构方法
System.out.println(pt1.getX());//7
}
private static void setProperties(ReflectPoint pt1, String propertyName,
Object value) throws IntrospectionException,
IllegalAccessException, InvocationTargetException {
PropertyDescriptor pd2 = new PropertyDescriptor(propertyName,pt1.getClass());
Method methodSetX = pd2.getWriteMethod();
methodSetX.invoke(pt1, value);
}
private static Object getProperty(Object pt1, String propertyName)
throws IntrospectionException, IllegalAccessException,
InvocationTargetException {
PropertyDescriptor pd = new PropertyDescriptor(propertyName,pt1.getClass());
Method methodGetX = pd.getReadMethod();
Object retVal = methodGetX.invoke(pt1);
return retVal;
//2,采用遍历方法较复杂,但可看出内省与JavaBean的层次关系: Inspector-->BeanInfo-->PropertyDescriptor
/* BeanInfo beanInfo = Introspector.getBeanInfo(pt1.getClass());//1先传入reflectPoint对象Java类;
//2获取各种属性描述类对象,
PropertyDescriptor[] pds = beanInfo.getPropertyDescriptors();
Object retVal = null;
for(PropertyDescriptor pd : pds){
if(pd.getName().equals(propertyName))//3遍历到针对propertyName的pd对象,getName()得到属性名称
{
Method methodGetX = pd.getReadMethod();//4获得方法methodGetX的Java类
retVal = methodGetX.invoke(pt1);//5传入对象返回属性的值;
break;
}
}
return retVal;
}
}
/**
* 3,beanutils包导入应用,重要掌握:
* BeanUtils和PropertyUtils
*
* 3.1,BeanUtils.setProperty(Object bean, String name, String value);
* 例如:BeanUtils.setProperty(pt1, "x", "9");//BeanUtils把属性的 值 都按子串引用
* BeanUtils.getProperty(pt1, "x");
*
* 3.2,类似BeanUtils的PropertyUtils!!!
PropertyUtils.setProperty(pt1,"x",9);//注意9,用本身的类型,不作类型转换;
System.out.println(PropertyUtils.getProperty(pt1, "x").getClass());
*/
/**
* 4,Java7的新特性:map类简化写法,并可用BeanUtils.setProperty()方法设置键值!
Map map = {name:"zxx",age:18);
BeanUtils.setProperty(map, "name", "lhm");
}*/
*/