2012-02-29 136 views
2

我发现this answer关于克隆java对象。然而,在那里接受的答案中,克隆对象完全是一个新实例吗?我的意思是不是一个链接的副本?克隆Java对象

我在问这个,因为我需要克隆的java对象是一个“全局对象”,它在某个时间点被更新。在某些时候,我需要“快照”这个对象,并且本质上是放在一个HashMap上。

+0

定义“链接副本”的意思。 – NPE 2012-02-29 08:42:26

+0

我的意思是,在高级链接副本中,具有不同实例的副本,但是当我更改副本更改的源时。 – xybrek 2012-02-29 08:52:57

+0

我认为正确的名词是“浅拷贝”,所以在我的问题链接的帖子上接受的答案是浅拷贝。那就是我的意思。 – xybrek 2012-02-29 08:58:33

回答

2

接受的答案其他问题简要说明拷贝构造函数,当然,这种模式将创建新的对象,可以用于创建这些快照。

新对象将获取原始对象的当前状态。这对于字符串和Java基元很容易。

对于对象来说,它更棘手:当前状态是指向另一个对象的指针,如果其他对象发生更改,则更改将反映在快照中。如果你需要避免这种情况,那么你也必须克隆这些对象(深层克隆)。

通过复制构造函数克隆的“问题”:可复制的类需要提供这样的构造函数。很简单,如果你拥有源代码 - 那么你可以自己实现它。否则,您可能需要使用Reflection API并实施一个克隆工厂,这至少会......错误,具有挑战性。

+0

是的,我可能需要做深入的克隆。 – xybrek 2012-02-29 08:53:52

1

你必须确定你想克隆多深。 无论如何,这不是真正的克隆。最好实施Clonable并深层复制任何相关领域。其他字段对象可以被引用。

+0

我只需要确保源对象中的HashMap字段中的对象被复制到克隆对象。 – xybrek 2012-02-29 08:50:14

1

可以使用复制构造函数在临时变量中创建对象的克隆。

public class foo { 
    private int i = 0; 

    public foo() { this.i = 5; } 
    public foo(foo orig) { this.i = orig.getI(); } 

    public getI() { return this.i; } 
} 

并且你使用这样的:(!应该)

foo a = new foo(); 
foo b = new foo(a); 
+0

使用这种方法,我需要输入复制构造函数中要复制的每个字段。如果我有一百个字段,那么我需要手动复制每一个字段? – xybrek 2012-02-29 08:51:40

+0

是的,我测试过了,Java不提供默认的拷贝构造函数。 – Odinn 2012-02-29 08:59:50