内省:IntroSpector,意思为检查、视察。对内部进行检查,了解内部细节。主要用于对JavaBean进行操作。
JavaBean是一种特殊的类,主要用于传递数据信息,这种java类中的方法主要用于访问私有的字段,且方法名符合一定的规则。
譬如:要获取age属性,那么方法名要写成getAge()。
方法名要以get或set,符合这个规则的类就叫JavaBean。
这种javabean的实例对象,称为值对象VO(ValueObject)。
一个符合JavaBean特点的类可以当做普通类一样进行使用,但把它当做JavaBean会更方便。
JDK中提供了JavaBean进行操作的一些API,这套API成为内省。
一个java类不一定要当做javabean来操作;一个javabean一定可以当做一个普通java类来操作。
get方法没有传入参数,有返回类型,访问权限为public;
set方法有传入参数,没有返回类型,访问权限为public。
如果把一个java类当一个javabean来看,javabean的属性是根据get和set方法的名称来推断出来的;
如:
class Person{
private int x;
public int getAge(){
return x;
}
public void setAge(int age){
this.x = age;
}
}
person 当做一个javabean来看,那么person类的属性是根据方法名推断出来的,从外部来看,根本看不到java类内部的成员变量。
setId()的属性名-->id
isLast()的属性名-->last
setCPU()的属性名-->CPU
getUPS()的属性名-->UPS
总之,如果set或get后面第一个字母是大写,第二个字母是小写,则把属性名第一个字母改为小写。
下面介绍利用内省获取javabean中某个属性
public class IntroSpectorDemo {
public static void main(String[] args) throws Exception {
ReflectPoint2 pt1 = new ReflectPoint2(3,5);
String propertyName="x";
//"x"-->"X"-->"getX"-->"MethodGetX"-->
Object retVal = getProperty(pt1, propertyName);
System.out.println(retVal);
Object value = 7;
setProperties(pt1, propertyName, value);
//选中pt1.getX(),ALT+/可以自动填上输出语句
System.out.println(pt1.getX());;
}
①private static void setProperties(Object 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);
BeanInfo beanInfo = Introspector.getBeanInfo(pt1.getClass());
PropertyDescriptor[] pds = beanInfo.getPropertyDescriptors();//得到所有属性描述
Object retVal = null;
for(PropertyDescriptor pd1:pds){
if(pd1.getName().equals(propertyName)){
Method methodGetX = pd1.getReadMethod();
retVal = methodGetX.invoke(pt1);//pt1对象调用methodGetX方法
break;
}
}
return retVal;
}
}
①和②是两种不同方法:
①直接用PropertyDescriptor类的构造方法获取指定属性的属性描述,再利用PropertyDescriptor类的对象获取读取属性的方法。
②采用遍历BeanInfo的所有属性的方式来查找某个RelectPoint对象的x属性。在程序中把一个类当做javabean来看,调用IntroSpector.getBeanInfo方法,得到BeanInfo对象。这个封装了这个javabean的所有结果信息。
BeanInfo不能得到某个属性的描述,只能得到所有的属性描述。