我需要澄清Java中深层复制,浅层复制和克隆之间的区别
最佳答案
不幸的是,“浅拷贝”,“深拷贝”和“克隆”都是定义不明确的术语。
在Java上下文中,我们首先需要在“复制值”和“复制对象”之间进行区分。
int a = 1;
int b = a; // copying a value
int[] s = new int[]{42};
int[] t = s; // copying a value (the object reference for the array above)
StringBuffer sb = new StringBuffer("Hi mom");
// copying an object.
StringBuffer sb2 = new StringBuffer(sb);
简而言之,对类型为引用类型的变量的引用分配是“复制值”,其中值是对象引用。要复制对象,某些东西需要显式地或在幕后使用
new
。现在用于对象的“浅”复制与“深”复制。浅复制通常意味着仅复制对象的一个级别,而深复制通常意味着复制多个级别的对象。问题在于确定水平是什么意思。考虑一下:
public class Example {
public int foo;
public int[] bar;
public Example() { };
public Example(int foo, int[] bar) { this.foo = foo; this.bar = bar; };
}
Example eg1 = new Example(1, new int[]{1, 2});
Example eg2 = ...
正常的解释是
eg1
的“浅”副本是一个新的Example
对象,该对象的foo
等于1,并且bar
字段引用的数组与原始数组相同;例如Example eg2 = new Example(eg1.foo, eg1.bar);
eg1
的“深层”副本的常规解释是一个新的Example
对象,其foo
等于1,并且bar
字段引用原始数组的副本;例如Example eg2 = new Example(eg1.foo, Arrays.copy(eg1.bar));
(来自C/C++背景的人们可能会说,引用分配会产生浅拷贝。但是,这通常不是Java上下文中的浅拷贝的意思……)
存在另外两个问题/不确定性 Realm :
最后,克隆。克隆是一种存在于所有类(和数组)上的方法,通常认为该方法可生成目标对象的副本。然而:
这是the javadoc所说的:
请注意,这是说克隆可能是目标对象,而另一极端是克隆可能与原始对象不相等。并假设甚至支持克隆。
简而言之,对于每个Java类,克隆都可能意味着不同的东西。
有人争辩(如@supercat在评论中所做的那样)Java
clone()
方法已损坏。但是我认为正确的结论是,克隆的概念在面向对象环境中被打破了。在AFAIK中,不可能开发出一个统一的克隆模型,该模型在所有对象类型之间都是一致且可用的。