内省(Introspector)

Posted loveer

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了内省(Introspector)相关的知识,希望对你有一定的参考价值。

内省(Introspector) 是Java 语言对 JavaBean 类属性、事件的一种缺省处理方法。用来访问某个属性的 getter/setter 方法。

一.JavaBean

JavaBean是一种特殊的类,主要用于传递数据信息,这种类中的方法主要用于访问私有的字段,且方法名符合某种命名规则。如果在两个模块之间传递信息,可以将信息封装进JavaBean中,这种对象称为“值对象”(Value Object),或“VO”。方法比较少。这些信息储存在类的私有变量中,通过set()、get()获得。
Java JDK中提供了一套 API 用来访问某个属性的 getter/setter 方法,这就是内省(Introspector)。


二.JDK内省类库:PropertyDescriptor类

直接构造 PropertyDescriptors

User user = new User("jack", 21);
String propertyName = "name";
PropertyDescriptor namePd = new PropertyDescriptor(propertyName, User.class);
namePd.getWriteMethod().invoke(user, "tom");
namePd.getReadMethod().invoke(user);

主要方法:

  1. getPropertyType(),获得属性的Class对象;
  2. getReadMethod(),获得用于读取属性值的方法;getWriteMethod(),获得用于写入属性值的方法;
  3. hashCode(),获取对象的哈希值;
  4. setReadMethod(Method readMethod),设置用于读取属性值的方法;
  5. setWriteMethod(Method writeMethod),设置用于写入属性值的方法。

三.Introspector类

调用Introspector.getBeanInfo()方法,得到的BeanInfo对象(封装了这个类的属性的信息)。

    User user=new User();
    String userName="userName";

    BeanInfo beanInfo=Introspector.getBeanInfo(User.class);
    PropertyDescriptor[] proDescrtptors=beanInfo.getPropertyDescriptors();
    if(proDescrtptors!=null&&proDescrtptors.length>0)
      for(PropertyDescriptor propDesc:proDescrtptors)
        if(propDesc.getName().equals(userName))
          Method methodSetUserName=propDesc.getWriteMethod();
          methodSetUserName.invoke(user, "alan");
          break;
        
      

四.BeanUtils

Introspector操作较繁琐,所以所以Apache开发了一套简单、易用的API来操作Bean的属性——BeanUtils工具包。
BeanUtils工具本身也是一种内省的实现方法,所以也是借助于底层的getter和setter方法进行转换的。
BeanUtils设置属性值的时候,如果属性是基本数据类型,那么BeanUtils会自动帮我们进行数据类型的转换


BeanUtils.setProperty(bean, name, value);
其中bean是指你将要设置的对象,name指的是将要设置的属性(写成”属性名”),value(从配置文件中读取到到的字符串值)
BeanUtils.copyProperties(bean, name, value);
和上面的方法是完全一样的。
ConvertUtils.register(Converter converter , ..);
当需要将String数据转换成引用数据类型(自定义数据类型时),需要使用此方法实现转换。
BeanUtils.populate(bean,Map);
其中Map中的key必须与目标对象中的属性名相同,否则不能实现拷贝。
BeanUtils.copyProperties(newObject,oldObject);
实现对象的拷贝,谨慎使用这个copyproperties这个功能,相同的属性都会被替换,不管是否有值

// 将对象转换为Map
User user = new User();
Map userMap = BeanUtils.describe(user);

// 将Map转换为对象
Map userMap = new HashMap();
User user = new User();
BeanUtils.populate(user,userMap);

对象数据和Map之间互相转化


当用到BeanUtils的populate、copyProperties方法或者getProperty,setProperty方法其实都会调用convert进行转换
Converter只支持一些基本的类型,甚至连java.util.Date类型也不支持。而且它比较笨的一个地方是当遇到不认识的类型时,居然会抛出异常来。
这个时候就需要给类型注册转换器。比如:意思是所以需要转成Date类型的数据都要通过DateLocaleConverter这个转换器的处理。
ConvertUtils.register(new DateLocaleConverter(), Date.class);

        //Person的birth变量是日期类型
        Map map = new HashMap();  
        //自带转化器转化时间格式
        map.put("birth", "2010-10-10");  
        ConvertUtils.register(new DateLocaleConverter(), Date.class);  
        Person p = new Person();  
        BeanUtils.populate(p, map);  
    String[] old = "12","2","3","5";  
    long[] new = (long[])ConvertUtils.convert(old, long.class); 
    int val = ConvertUtils.convert("2343",int.class);

以上是关于内省(Introspector)的主要内容,如果未能解决你的问题,请参考以下文章

内省(Introspector)

内省(Introspector)

内省Introspector(反射操作javaBean)

深入理解Java:内省(Introspector)

java内省Introspector

java内省 introspector