------- android培训、java培训、期待与您交流! ----------
内省
内省英文名称为IntroSpector,用于对JavaBean进行操作,即JDK中提供了JavaBean进行操作的一些API,这套API就称为内省
JavaBean是一种特殊的Java类,主要用于传递数据信息,这种Java类中的方法主要用于访问私有字段,且方法名符合某种命名规则。
例如:如果要在两个模块之间传递多个信息,可以将这些信息封装到一个JavaBean中,这种JavaBean的实例对象通常称之为值对象(Value Object,简称VO);这些信息在类中用私有字段来存储,如果读取或设置这些字段的值,则需要通过一些相应的方法来访问,但这些方法的名称应该怎么命名?
JavaBean的属性就是根据其中setter和getter方法来确定的,而不是根据其中的成员变量;如方法名为setId,去掉set前缀,剩余部分就是属性名。
属性名名规则:
1、如果第二个字母是小写的,则把第一个字母变成小写的;
2、如果第二个字母是大写的,则把第一个字母变成大写的。
例如:setId的属性名为id
getLast的属性名为last
setCPUd的属性名为CPU
getUPS的属性名为UPS
总之,一个类被当作JavaBean使用时,JavaBean的属性是根据方法名推断出来的,它根本看不到java类内部的成员变量。
一个符合JavaBean特点的类可以当作普通类一样进行使用,但把它当JavaBean用能带来一些额外的好处,好处如下:
1、在JavaEE开发中,经常要使用到JavaBean,很多环境就要求按JavaBean方式进行操作;
2、如果自己通过getX方法来访问私有的x,会有一定的难度,但用内省这套API操作JavaBean比用普通类的方式更方便。
内省操作JavaBean有两种方法如下:
1、通过Introspector类获得Bean对象的 BeanInfo,然后通过 BeanInfo 来获取属性的描述器( PropertyDescriptor ),通过这个属性描述器就可以获取某个属性对应的 getter/setter 方法,然后通过反射机制来调用这些方法;
2、通过PropertyDescriptor来操作Bean对象。
综合实例如下:
RefelectPoint类: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; public class IntrospectorTest { public static void main(String[] args)throws Exception { ReflectPoint pt1=new ReflectPoint(3,5);//此为带有x,y属性的类 String propertyName="x";//属性名 Object retVal = getProperty(pt1, propertyName);//方法调用 System.out.println(retVal); Object value=9;//给属性赋值的参数 setProperty(pt1, propertyName, value);//方法调用 System.out.println(pt1.getX()); BeanUtils.setProperty(pt1, "birthday.time", "111"); System.out.println(BeanUtils.getProperty(pt1, "birthday.time")); } /*内省简单应用方式*/ private static void setProperty(Object pt1, String propertyName,//方法抽取,设置属性 Object value) throws IntrospectionException, IllegalAccessException, InvocationTargetException { //此方法为通过PropertyDescriptor来操作Bean对象,相对比较简单 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 { /*此方法为通过Introspector类获得Bean对象的 BeanInfo,然后通过 BeanInfo 来获取属性的描述器( PropertyDescriptor ),通过这个属性描述器就可以获取某个属性对应的 getter/setter 方法,然后通过反射机制来调用这些方法;*/ BeanInfo beanInfo=Introspector.getBeanInfo(pt1.getClass());//获得BeanInfo对象 PropertyDescriptor[] pds=beanInfo.getPropertyDescriptors(); Object retVal=null; for(PropertyDescriptor pd:pds){//此循环为获得对应的属性获取方法,以获得属性值 if(pd.getName().equals(propertyName)){ Method methodGetX=pd.getReadMethod(); retVal=methodGetX.invoke(pt1); break; } } return retVal; } }
public class ReflectPoint { private int x; public int y; public ReflectPoint(int x, int y) { super(); this.x = x; this.y = y; } public int getX() { return x; } public void setX(int x) { this.x = x; } public int getY() { return y; } public void setY(int y) { this.y = y; } }
通过以上实例基本了解了内省对JavaBean的操作方式,但为了提高代码效率,其它人又提供了另一种方法,即BeanUtils工具包,专门用于对对象属性的操作,此工具包大大提高了效率。
BeanUtils工具包在MyEclipse工程下建立路径的流程:
1、先下载BeanUtils工具包中的两个jar包,即commons-beanutils.jar和commons-logging.jar;
2、把相应的工程目录下建一个文件夹,然后将两个jar包复制到此文件夹下;
3、对两个jar进行路径创建,即选中jar包点右键,选择Build Path下的Add to Build Path创建相应的路径。
实例如下:
import org.apache.commons.beanutils.BeanUtils; public class IntrospectorTest { public static void main(String[] args)throws Exception { ReflectPoint pt1=new ReflectPoint(3,5);//此为带有x,y属性的类 /*与上一个实例相比,如果采用BeanUtils工具包来获取属性x的值或设置值都变得很简单,大大提高了效率*/ BeanUtils.setProperty(pt1, "x", "555"); System.out.println(BeanUtils.getProperty(pt1, "x")); /*除此之外,BeanUtils工具包还支持属性的级联操作,如有一个成员变量为birthday,birthday又是一个Date对象,birthday对象下又有属性值time,这时BeanUtils工具包可以直接进行操作, 操作方式如下*/ BeanUtils.setProperty(pt1, "birthday.time", "111"); System.out.println(BeanUtils.getProperty(pt1, "birthday.time")); } }
RefelectPoint类:
import java.util.Date; public class ReflectPoint { private Date birthday=new Date(); private int x; public int y; public ReflectPoint(int x, int y) { super(); this.x = x; this.y = y; } public int getX() { return x; } public void setX(int x) { this.x = x; } public int getY() { return y; } public void setY(int y) { this.y = y; } public Date getBirthday() { return birthday; } public void setBirthday(Date birthday) { this.birthday = birthday; } }
除此之外,BeanUtils工具包还支持直接将属性值和Map集合间的相互转换等,非常方便。