zoukankan      html  css  js  c++  java
  • 内省(Introspector)

    内省(Introspector) 是Java语言对 JavaBean 类属性、事件的一种缺省处理方法。用来访问某个属性的 getter/setter 方法。
    内省大部分是在写一些框架或者工具的时候会用到。比如说 spring 初始化 bean。

    JavaBean

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

    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;
            }
          }
    

    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),设置用于写入属性值的方法。
    

    BeanUtils基本操作

    Introspector操作较繁琐,所以所以Apache开发了一套简单、易用的API来操作Bean的属性——BeanUtils工具包:
    
        BeanUtils工具本身也是一种内省的实现方法,所以也是借助于底层的getter和setter方法进行转换的。
    
        BeanUtils设置属性值的时候,如果属性是基本数据类型,那么BeanUtils会自动帮我们进行数据类型的转换。
    
    
    BeanUtils.copyProperty(Object bean, String name, Object value);
    BeanUtils.setProperty(Object bean, String name, Object value)
        其中bean是指你将要设置的对象,name指的是将要设置的属性(写成"属性名"),value(值)
    
    ConvertUtils.register(Converter converter, Class<?> clazz);
        当需要将String数据转换成引用数据类型(自定义数据类型时),需要使用此方法实现转换。
    
    BeanUtils.populate(Object bean, Map<String, ? extends Object> properties);
        其中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);
    

    BeanUtils convert转换

    当用到BeanUtils的populate、copyProperties,getProperty,setProperty等方法其实都会调用convert进行转换:
    
        但Converter只支持一些基本的类型,甚至连java.util.Date类型也不支持。当遇到不认识的类型时,会抛出异常来。
    
            String[] old = {"12","2","3","5"};
            long[] new = (long[])ConvertUtils.convert(old, long.class);    //将String数组转换成long数组
            int val = ConvertUtils.convert("2343",int.class);    //字符串转int
    
    
    这个时候就需要给类型注册转换器。比如:需要转成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);
    
  • 相关阅读:
    POJ:1185-炮兵阵地(状压dp入门)
    LightOj:1422-Halloween Costumes
    HDU:4632-Palindrome subsequence
    POJ:2955-Brackets(经典:括号匹配)
    POJ:2342-Anniversary party(树形dp入门题目)
    HUD:2853-Assignment(KM算法+hash)
    HDU:2255-奔小康赚大钱(KM算法模板)
    POJ:3020-Antenna Placement(二分图的最小路径覆盖)
    POJ:3041-Asteroids(匈牙利算法模板)
    SVN
  • 原文地址:https://www.cnblogs.com/loveer/p/11302442.html
Copyright © 2011-2022 走看看