0
点赞
收藏
分享

微信扫一扫

如何在Java中复制对象(深、浅拷贝)?


如何在Java中复制对象?

考虑下面的代码:

DummyBean dum = new DummyBean();
dum.setDummy("foo");
System.out.println(dum.getDummy()); // prints 'foo'

DummyBean dumtwo = dum;
System.out.println(dumtwo.getDummy()); // prints 'foo'

dum.setDummy("bar");
System.out.println(dumtwo.getDummy()); // prints 'bar' but it should print 'foo'

因此,我想复制dum到dumtwo并且更改dum而不影响dumtwo。但是上面的代码没有做到这一点。当我更改时dum,也会发生相同的更改dumtwo。

我想,当我说时dumtwo = dum,Java仅复制参考。那么,有什么方法可以创建的新副本dum并将其分配给dumtwo?

高分回答:

创建一个副本构造函数:

class DummyBean {
private String dummy;

public DummyBean(DummyBean another){
this.dummy = another.dummy; // you can access

每个对象都有一个克隆方法,可用于复制对象,但不要使用它。创建类和执行不正确的克隆方法太容易了。如果您要这样做,请至少阅读Joshua Bloch在Effective Java中要说的话。

高分回答:

基本: Java中的对象复制。

让我们假设一个对象- obj1,它包含两个对象,containedObj1和containedObj2。 在此处输入图片说明

如何在Java中复制对象(深、浅拷贝)?_java_02

浅表复制: 浅表复制创建instance相同类的新表,并将所有字段复制到新实例并返回它。对象类提供了一种clone方法,并提供了对浅表复制的支持。 在此处输入图片说明

如何在Java中复制对象(深、浅拷贝)?_掘金·日新计划_03

深度复制: 深度复制是将对象及其引用的对象一起复制时发生的。下图显示了obj1在其上执行深度复制之后的情况。不仅已obj1被复制,而且包含在其中的对象也已被复制。我们可以Java Object Serialization用来制作深层副本。不幸的是,这种方法也存在一些问题(详细示例)。 在此处输入图片说明

如何在Java中复制对象(深、浅拷贝)?_掘金·日新计划_04

可能的问题: clone难以正确实施。 最好使用防御性复制,复制构造函数(如@egaga回复)或静态工厂方法。

如果您有一个对象,就知道它有一个公共clone()方法,但是在编译时却不知道该对象的类型,那么您就遇到了问题。Java有一个名为的接口Cloneable。在实践中,如果要创建对象,则应实现此接口Cloneable。Object.clone是protected,因此我们必须使用公共方法覆盖它,以便对其进行访问。

当我们尝试对复杂对象进行深度复制时,会出现另一个问题。假设所有成员对象变量的方法也都进行深层复制,那么进行假设的风险太大。您必须控制所有类中的代码。clone()

例如,org.apache.commons.lang.SerializationUtils将具有使用序列化(来源)进行深度克隆的方法。如果我们需要克隆Bean,那么org.apache.commons.beanutils(源)中有几个实用程序方法。

cloneBean 即使bean类本身未实现Cloneable,也会基于可用的属性getter和setter克隆bean。copyProperties 在属性名称相同的所有情况下,都会将属性值从原始Bean复制到目标Bean。


举报

相关推荐

0 条评论