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

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属性 并赋值26
		System.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
	}

}


我们看下执行结果:




本篇结束。


  • 3
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值