在 java 中将一个对象镜像到另一个对象

Mirror an object to another in java

有两个不同的 类: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();

问题:

我好像在重复那些二传手。我不必编写那些重复的 setter 的任何库或方法?感觉可以用反射,但不知道具体怎么用。

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

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

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

在结构化语言中,某人会非常非常 感到非常惊讶。在名义语言中,这不是问题(注意类型是 完全命名空间 - 它们有一个包名称,意思是,即使使用同音异义词你也不会 运行 遇到任何问题。java.util.Listjava.awt.List 在 java 生态系统中的任何地方都无法互换。枪和祖母)。

类似的原则适用于此:A 可能看起来很像 B,但在 java 中,A 不是 B。事实上,A 的 'attriA' 字段具有与 B 的 'attriA' 字段绝对没有任何关系。它们碰巧具有相同的名称和相同的类型这一事实纯属巧合。其实就是一个实现细节(privateAPI);您应该能够重命名该字段,并且现有的代码都不应关心该字段,否则会中断。

因此,你不应该想要这个;这不是 java 风格。

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

既然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);

在 Apache 的 BeanUtils 中,您完全可以期待一件事。 https://mvnrepository.com/artifact/commons-beanutils/commons-beanutils/1.9.2

BeanUtils.copyProperties(objectB, objectA);