JAVA - 如何将一个对象的属性复制到另一个具有相同属性的对象中?

8
假设我们有一个这样定义的A对象:
public class ObjectA {
    private Attribute a1;
    private Attribute a2;
    private Attribute a3;
}

由于某些原因,我需要创建第二个对象B,只包含对象A的前两个属性:

public class ObjectB {
    private Attribute a1;
    private Attribute a2;
}

所以我的问题是:复制对象A到对象B的最佳方法是什么? 我一直在一个一个地通过getter和setter复制属性,但有时我会想,肯定有更好的方法来做这件事情!特别是当对象具有许多属性时,我必须写很长的代码才能将它们全部复制到第二个对象B中...
非常感谢 :)
编辑:我被提示“可能与另一个问题重复”:如何在Java中复制一个对象? 我的问题在某种程度上略有不同,因为我正在处理两个不完全相同但共享相同属性的不同对象!

3
请看使用反射的Apache Commons BeanUtils:http://commons.apache.org/proper/commons-beanutils/ - Arnaud
2
http://dozer.sourceforge.net/ - Tom
2
可能是如何在Java中复制对象?的重复问题。 - M. Suurland
1
我同意,这不是关于复制对象,而是在不同层次结构的对象之间复制(部分)数据。Dozer 是一个很好的工具,因为它可以自动处理常见属性(相同的名称和类型),而无需编写任何额外的代码。 - Thomas
@hahn,你能给我一个链接吗?其中有亿万个问题已经回答了我的问题吗?我找不到 :/ - Hyukchan Kwon
显示剩余4条评论
3个回答

7

6

我来进一步解释一下:

使用Dozer,操作可以非常简单:

Mapper mapper = new DozerBeanMapper();
ObjectA source = new ObjectA();
ObjectB target = mapper.map(source , ObjectB.class);

或者如果你的目标类没有无参构造函数:

ObjectA source = new ObjectA();
ObjectB target = new ObjectB(/*args*/);
mapper.map(source, target );

来自文档(由我强调):

执行Dozer映射后,结果将是一个包含与源对象具有相同字段名称的所有字段值的目标对象的新实例。如果任何映射属性具有不同的数据类型,则Dozer映射引擎将自动执行数据类型转换。


看起来非常接近我要找的东西。Dozer也处理父属性吗?假设现在A对象正在扩展具有属性a4的C对象,我想将其复制到B对象的属性a4中,怎么办? - Hyukchan Kwon
@HyukchanKwon 如果ObjectB也有属性a4,那么是的,它应该被复制。然而,在大多数实际应用程序中,映射并不那么简单,例如你可能需要提供一些代码来处理非平凡的映射(如只读、自定义类型转换、不同的名称等)。 - Thomas
谢谢 @Thomas :) 我会尝试的! - Hyukchan Kwon
我尝试了Doze,对于基本的映射,只需几行代码就可以非常好地工作!谢谢 :) - Hyukchan Kwon

1
你需要的是对象映射器。尝试使用 OrikaDozer。 对象不需要是相同类型的。在映射时,如果找到相同名称和类型的属性,则会自动进行映射。
MapperFacade mapper = mapperFactory.getMapperFacade();
UserDTO userDTO = new UserDTO();
userDTO.setName("xyz");
..
User user = mapper.map(userDTO, User.class);

如果需要映射不同的属性名称,您也可以进行自定义。

MapperFactory mapperFactory = new DefaultMapperFactory.Builder().build();
mapperFactory.classMap(UserDTO.class, User.class)
            .field("name", "username")
            .byDefault().register();
mapper = mapperFactory.getMapperFacade();
...
User user = mapper.map(userDTO, User.class);

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接