【问题标题】:Mirror an object to another in java在java中将一个对象镜像到另一个对象
【发布时间】:2020-07-09 20:44:32
【问题描述】:

有两个不同的类:A 和 B。它们具有完全相同的字段名称。假设它们的定义如下:

import lombok.Builder;
import lombok.Data;

@Data
@Builder
public class A {
  private String attriA;
  private String attriB;
  private String attriC;
}

import lombok.Builder;
import lombok.Data;

@Data
@Builder
public class B {
  private String attriA;
  private String attriB;
  private String attriC;
}

假设我有一个 A 的实例 objectA,我想将它翻译成 B。通过所有手动工作,它看起来像:

B objectB = B.builder()
        .attriA(objectA.getAttriA())
        .attriB(objectA.getAttriB())
        .attriC(objectA.getAttriC())
        .build();

问题:

似乎我在重复那些二传手。我不必编写那些重复的设置器的任何库或方法?感觉我们可能会使用反射,但不知道具体如何。

【问题讨论】:

    标签: java reflection dry


    【解决方案1】:

    一般来说,java 遵循名义类型而不是结构类型的概念。把这个论点带回家,想象一下这两个接口:

    public interface Camera {
        public void shoot(Person target);
    }
    
    public interface Gun {
        public void shoot(Person target);
    }
    

    在结构化语言中,某人会有一个非常、非常令人讨厌的惊喜。在名义语言中,这不是问题(请注意,类型是完全命名空间 - 它们有一个包名,意思是,即使使用同音异义词,你也不会遇到任何问题。@987654323 @ 和 java.awt.List 在 Java 生态系统中的任何地方都无法或以任何形式互换。枪和奶奶)。

    这里也适用类似的原则:A 可能看起来很像 B,但在 Java 中,A 不是 B。事实上,A 的 'attriA' 字段与 B 的 'attriA 绝对没有任何关系' 场地。他们碰巧有相同的名字和相同的类型,这纯属巧合。实际上,这是一个实现细节(私有 API);您应该能够重命名该字段,并且现有的代码不应该关心或中断。

    因此,您不应该这样;它不是 java 风格的。

    但如果你坚持,MapStruct 可能会在这里为你做点什么(不过我不推荐它!)。

    【讨论】:

      【解决方案2】:

      由于AB 似乎没有任何共同之处,除了听起来巧合的相同属性,至少你没有说它们是相互继承的,你可以编写自己的映射器方法或功能。然后,您可以在想从 A 创建 B 时调用此函数并节省一些输入:

      Function<A,B> mirrorToB = a ->  B.builder()
                                       .attriA(objectA.getAttriA())
                                       .attriB(objectA.getAttriB())
                                       .attriC(objectA.getAttriC())
                                       .build();
      
      B objectB = mirrorToB.apply(objectA);
      

      【讨论】:

        【解决方案3】:

        您在 Apache 的 BeanUtils 中确实有一件事。 https://mvnrepository.com/artifact/commons-beanutils/commons-beanutils/1.9.2

        BeanUtils.copyProperties(objectB, objectA);
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2018-02-10
          • 2021-11-04
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多