在业务开发中,常会遇到如下情形:要根据持久化获得的bean信息A,构造一个新的bean-B,B需要A中的大多数属性信息,但根据业务需要修改部分属性信息,如果将A的引用直接复制给B的话,就会丢失旧有的数据,此时可以通过clone完成,但clone需要修改bean类,而且偶尔的业务需求导致类重新定义,可以视为代码污染,此时可以通过java的内省机制来实现对象间属性的复制。



    内省是Java中Bean类属性的一种缺省的处理方式。例如,有一个类Person,其中有个age属性,可通过setAge()和getAge()方法获取/设置age的值。通过setAge()/getAge()获取/设置age的值是Java中的默认的处理规则,Java提供了一套API来访问某个属性的setAge()/getAge()。通用的用法通过类 Introspector 来获取某个对象的 BeanInfo 信息,然后通过 BeanInfo 来获取属性的描述器( PropertyDescriptor ),通过这个属性描述器就可以获取某个属性对应的 getter/setter 方法,然后通过反射机制来调用这些方法





public static void main(String[] args) throws Exception { 
 
 
 
 
 

  PersonInfo personInfoA = new PersonInfo(); 

 

   personInfoA.setName("tiger"); 

 

   personInfoA.setAge(28); 

 
 

   PersonInfo personInfoB = new PersonInfo(); 

 

   copyProperties(personInfoB, personInfoA); 

 

   personInfoB.setName(personInfoB.getName()+"temp"); 

 

   personInfoB.setAge(personInfoB.getAge()+1); 

 

   System.err.println(personInfoA.toString()); 

 

   System.err.println(personInfoB.toString()); 

 
 
 
 

  } 

 
 
 
 

   public static void copyProperties(Object personInfoB , Object personInfoA ) throws Exception{ 

 

      

 

   BeanInfo beanInfo = Introspector.getBeanInfo(personInfoA.getClass()); 

 

    PropertyDescriptor[] props = beanInfo.getPropertyDescriptors(); 

 

    for (int i = 0; i < props.length; i++) { 

 

        PropertyDescriptor srcProp = props[i]; 

 

        // 获取对应的属性信息 

 

        PropertyDescriptor destProp = findProperty(personInfoB, srcProp.getName()); 

 

        if ((destProp != null) && (destProp.getWriteMethod() != null) && (srcProp.getReadMethod() != null)) 

 

     try { 

 

        // 找到源对象属性值 

 

         Object srcVal = srcProp.getReadMethod().invoke(personInfoA, new Object[0]); 

 

        // 调用目标对象的属性赋值方法,实现属性值复制 

 

         destProp.getWriteMethod().invoke(personInfoB, new Object[] { srcVal }); 

 

     } catch (Exception ex) { 

 

     } 

 

    } 

 

   } 

 

   public static class PersonInfo { 

 

   private String name; 

 

   private int age; 

 
 

   public String getName() { 

 

       return name; 

 

   } 

 
 

   public void setName(String name) { 

 

       this.name = name; 

 

   } 

 
 

   public int getAge() { 

 

       return age; 

 

   } 

 
 

   public void setAge(int age) { 

 

       this.age = age; 

 

   } 

 
 

      } 

 
 

      private static PropertyDescriptor findProperty(Object object, String name) throws IntrospectionException { 

 

  // 通过内省工具类获取属性信息 

 

   BeanInfo info = Introspector.getBeanInfo(object.getClass()); 

 

  // 获取属性描述信息 

 

   PropertyDescriptor[] properties = info.getPropertyDescriptors(); 

 

   for (int i = 0; i < properties.length; i++) { 

 

       PropertyDescriptor property = properties[i]; 

 

       if (property.getName().equals(name)) { 

 

    return property; 

 

       } 

 

   } 

 

   return null; 

 

      }