在 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.List
和 java.awt.List
在 java 生态系统中的任何地方都无法互换。枪和祖母)。
类似的原则适用于此:A 可能看起来很像 B,但在 java 中,A 不是 B。事实上,A 的 'attriA' 字段具有与 B 的 'attriA' 字段绝对没有任何关系。它们碰巧具有相同的名称和相同的类型这一事实纯属巧合。其实就是一个实现细节(privateAPI);您应该能够重命名该字段,并且现有的代码都不应关心该字段,否则会中断。
因此,你不应该想要这个;这不是 java 风格。
但如果你坚持,也许 MapStruct 可以在这里为你做点什么(不过我不推荐它!)。
既然A
和B
除了巧合的发音属性外似乎没有任何共同点,至少你没有说它们是相互继承的,你可以编写自己的映射器方法或函数。然后,只要您想从 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);
有两个不同的 类: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.List
和 java.awt.List
在 java 生态系统中的任何地方都无法互换。枪和祖母)。
类似的原则适用于此:A 可能看起来很像 B,但在 java 中,A 不是 B。事实上,A 的 'attriA' 字段具有与 B 的 'attriA' 字段绝对没有任何关系。它们碰巧具有相同的名称和相同的类型这一事实纯属巧合。其实就是一个实现细节(privateAPI);您应该能够重命名该字段,并且现有的代码都不应关心该字段,否则会中断。
因此,你不应该想要这个;这不是 java 风格。
但如果你坚持,也许 MapStruct 可以在这里为你做点什么(不过我不推荐它!)。
既然A
和B
除了巧合的发音属性外似乎没有任何共同点,至少你没有说它们是相互继承的,你可以编写自己的映射器方法或函数。然后,只要您想从 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);