Java--introspector(内省)操作bean属性

来源:互联网 发布:es java api 查询 编辑:程序博客网 时间:2024/06/05 21:30

Introspector

英译中为:内省

作用:一般在开发框架时,当需要操作一个JavaBean时,如果一直用反射来操作,显得很麻烦;所以sun公司开发一套API专门来用来操作JavaBean的属性,二者结合,干活不累。

何为bean:咖啡"爪哇"的别名,开个玩笑,其实就是一个Java类,我们天天都在使用。




我们定义一个实体对象类,封装一些属性:



Person.java

package com.appleyk.introspector;public class Peroson {   private String name;    private String sex ;   private int    age ;      public String getName() {   return name;   }   public void setName(String name) {   this.name = name;   }   public String getSex() {   return sex;   }   public void setSex(String sex) {   this.sex = sex;   }   public int getAge() {   return age;   }   public void setAge(int age) {   this.age = age;   }      public void setAB(String ab){      }    public String getCD(){   return null;   }      }

除了我们定义的三个私有变量(name,sex,age)有特定的属性(getter 和 setter)外,我们又额外增加了两个"属性",一个是具有getter性质的函数getCD,一个是具有setter性质的setAB,ok,我们把Person类作为我们的测试JavaBean,暂时先放一放,我们开始介绍一下,本篇的主角Introspector,我们看下Java 1.8 API里面是怎么描述的:


Introspector类提供了一种标准的工具来了解目标Java Bean支持的属性,事件和方法。




API里我们继续翻找,找到了getBeanInfo方法的说明:



 

知道了类和对应的方法,我们现在来获得一下Person类的BeanInfo对象(对象里面的内容那是相当丰富!)


test.java:


package com.appleyk.introspector;import java.beans.BeanInfo;import java.beans.Introspector;public class Test {public static void main(String[] args) throws Exception{BeanInfo beanInfo = Introspector.getBeanInfo(Peroson.class);        System.out.println(beanInfo);}}

我们看下打印这个beanInfo对象,输出的是什么:




我去,这什么鬼东西,看不懂啊?  没关系,好吧,我们不研究这个对象本身是什么,而是研究利用这个对象我们能干什么,我们继续:


上面我们说了 ,我们是来操作Bean属性的,现在Person的BeanInfo信息我们拿到了,我们接下来,就来看下怎么获得Person类中的属性数组,我们不得不说一个类PropertyDescriptor,看下API是怎么描述的:



ok,目前的问题是,怎么利用Person类的BeanInfo获得这个(这些)属性呢?我们再来看一下BeanInfo对象有哪些方法:




ok,一目了然,我们开始写代码测试:


测试前,思考一个问题,如果,用上述getPropertyDescriptors方法,得到Person Bean的属性数组,那么,问题来了,数组里会有几个属性呢? 3个?还是3+2=5个?还是其他答案呢?


Test.java:


package com.appleyk.introspector;import java.beans.BeanInfo;import java.beans.Introspector;import java.beans.PropertyDescriptor;public class Test {public static void main(String[] args) throws Exception{BeanInfo beanInfo = Introspector.getBeanInfo(Peroson.class);    PropertyDescriptor[] pds = beanInfo.getPropertyDescriptors();for(PropertyDescriptor pd : pds){    System.out.println(pd.getName());}     }}


答案是3+2+1 = 6 个:




现在我们知道,Bean的属性,其实和Person类中定义了几个变量无关,而是和setter和getter有关,一对算作一个属性,如果落单的话,也算一个,因此,我们会看到,额外输出的属性名单中有我们的AB和CD:



但是这个属性是哪里冒出来的呢?


不卖关子了,所有类的基类(超类)都是Object,Person也不例外,我们看下,这个class属性是不是来自于Object,一样借助API:




我们怎么做到,从Person类的 BeanInfo对象中剔除掉基类的属性呢? 很简单,我们修改下getBeanInfo的参数调用:




上述的意思是,只得到Person类的BeanInfo,(stop)不要Object的BeanInfo


我们再来看下改后的执行效果(验证下):




上面说了怎么得到一个类的BeanInfo,以及怎么通过BeanInfo得到bean的属性数组,下面,我们通过demo来全篇演示一下如何操作Bean的属性:


放出demo之前,我们看下api中,关于属性类PropertyDescriptor的两个方法介绍:


getReadMethod :




getWriteMethod :






Test.java:


package com.appleyk.introspector;import java.beans.BeanInfo;import java.beans.Introspector;import java.beans.PropertyDescriptor;import java.lang.reflect.Method;public class Test {public static void main(String[] args) throws Exception{Peroson p = new Peroson();BeanInfo beanInfo = Introspector.getBeanInfo(Peroson.class,Object.class);    PropertyDescriptor[] pds = beanInfo.getPropertyDescriptors();System.out.println("----A、遍历Person Bean属性数组------------");    for(PropertyDescriptor pd : pds){    System.out.println(pd.getName());}    System.out.println("----B、得到Person Bean的age属性------------");    //构造方法  PropertyDescriptor(String propertyName, 类<?> beanClass) PropertyDescriptor pd =new PropertyDescriptor("age", Peroson.class);System.out.println(pd.getName());System.out.println("----C、得到Person Bean的age属性的类型------------");System.out.println(pd.getPropertyType());System.out.println("----D、给Person Bean的age属性赋值------------");Method setter = pd.getWriteMethod();//得到写方法   即setter属性setter.invoke(p, 26);               //唤起(调用)Person对象p的age的setter属性 并赋值26System.out.println("set age = 26");System.out.println("----E、读取Person Bean的age属性------------");Method getter = pd.getReadMethod();   //得到读方法 即getter属性System.out.println("get age = "+getter.invoke(p)); //唤起(调用)Person对象p的age的getter属性 得到26}}


我们看下执行结果:




本篇结束。


原创粉丝点击