使用自动转换

时间:2017-05-05 05:58:21

标签: java object dynamic reflection apache-commons-beanutils

我希望将一些字段从一个java对象动态复制到其他java对象。 这些对象的类别不同

以下是方案

  
      
  1. 我有一些带有一些字段的资源类。几乎没有领域   在每个类中,可由用户修改,但这些字段是   在所有资源类中都不相同。可修改字段列表   每个类都在一些数据结构中维护。

  2.   
  3. 大多数字段都是相似的,有些字段可以像一个字段一样可转换   原始和其他有包装类。有些字段应该是     从Number类型转换为String,反之亦然。

  4.   
  5. 大多数字段都是复杂的对象类型。

  6.   

今天可用的哪些库可以帮助我复制这些字段,并在需要时进行自动转换并进行深层复制? 之前我使用的是 BeanUtils ,但这并不是深层复制。它都不支持自动转换。

1 个答案:

答案 0 :(得分:0)

我认为spring框架可能有所帮助。这是我的spring-core-4.1.5的例子:

类声明:

public static class  A{
    private String a;
    private String b;
    private String c;
    private C d;
    private int e;
//getter&setter here

 public static class  C {
    private String aa;
    private String bb;
    private String cc;

    //getter&setter here

public static  class  B{
    private Integer a;
    private Long b;
    private Boolean c;
    private D d;
    private Integer e;

    //getter&setter here

 public static class  D {
    private Integer aa;
    private Long bb;
    private Boolean cc;

    //getter&setter here

class ObjectConverter implements  Converter<Object, Object> {
    private final ConversionService conversionService;
    private final Class targetClass;

    public ObjectConverter(ConversionService conversionService, Class targetClass) {
        this.conversionService = conversionService;
        this.targetClass = targetClass;
    }

    @Override
    public Object convert(Object source) {
        Object ret=null;
        try {
            ret = targetClass.newInstance();

            Field[] fields = targetClass.getDeclaredFields();
            for (Field field : fields) {
                PropertyDescriptor sourceDescriptor = new PropertyDescriptor(field.getName(),source.getClass());
                PropertyDescriptor targetDescriptor = new PropertyDescriptor(field.getName(),targetClass);

                if (sourceDescriptor.getReadMethod()==null || targetDescriptor.getWriteMethod() == null) {
                    //record error here
                    break;
                }

                Class<?> sourcePType = sourceDescriptor.getPropertyType();
                Class<?> targetPType = targetDescriptor.getPropertyType();
                if(conversionService.canConvert(sourcePType,targetPType)){
                    Object sourceValue = sourceDescriptor.getReadMethod().invoke(source);
                    Object targetValue = conversionService.convert(sourceValue, targetPType);
                    targetDescriptor.getWriteMethod().invoke(ret,targetValue);
                }
            }

        } catch (Exception e) {
            e.printStackTrace();
        }
        return ret;
    }
}

主要方法:

 A orgA = new A();
    orgA.a="123";
    orgA.b="1234567";
    orgA.c="1";
    orgA.d = new C();
    orgA.d.aa="321";
    orgA.d.bb="7654321";
    orgA.d.cc="0";
    orgA.e=-99;

    System.out.println(orgA);

    try {
        ConfigurableConversionService conversionService = new DefaultConversionService();

        //if you are not satisfied with the final A result, then
        //customize your own  Boolean->String Converter;
//            conversionService.addConverter(new Converter<Boolean, String>() {
//                @Override
//                public String convert(Boolean source) {
//                    return source==null||!source?"0":"1";
//                }
//            });

        conversionService.addConverter(A.class, B.class, new ObjectConverter(conversionService, B.class));
        conversionService.addConverter(B.class, A.class, new ObjectConverter(conversionService, A.class));

        conversionService.addConverter(C.class, D.class, new ObjectConverter(conversionService, D.class));
        conversionService.addConverter(D.class, C.class, new ObjectConverter(conversionService, C.class));

        B b = conversionService.convert(orgA, B.class);
        System.out.println(b);

        A a = conversionService.convert(b, A.class);
        System.out.println(a);

    } catch (Exception e) {
        e.printStackTrace();
    }

结果:

A {a =&#39; 123&#39;,b =&#39; 1234567&#39;,c =&#39; 1&#39;,d = C {aa =&#39; 321&# 39;,bb =&#39; 7654321&#39;,cc =&#39; 0&#39;},e = -99}
B {a = 123,b = 1234567,c =真,d = D {aa = 321,bb = 7654321,cc =假},e = -99}
A {a =&#39; 123&#39;,b =&#39; 1234567&#39;,c =&#39; true&#39;,d = C {aa =&#39; 321&#39;, bb =&#39; 7654321&#39;,cc =&#39; false&#39;},e = -99}