你所实施的是shallow复制。实施一个deep复制,你必须
改变
data[i] = other.data[i];
分配给某些事物copy of other.data[i]
to data[i]
。如何执行此操作取决于Position
班级。可能的替代方案是:
-
复制构造函数:
data[i] = new Position(other.data[i]);
-
工厂方法:
data[i] = createPosition(other.data[i]);
-
clone:
data[i] = (Position) other.data[i].clone();
Notes:
- 上面假设复制构造函数、工厂方法和克隆方法分别实现“正确”类型的复制,具体取决于 Position 类;见下文。
- The
clone
approach will only work if Position
explicitly supports it, and this is generally regarded as an inferior solution. Besides, you need to be aware that the native implementation of clone
(i.e. the Object.clone()
method) does a shallow copy1.
事实上,在Java中实现深度复制的一般问题很复杂。在这种情况下Position
类,我们会假设属性都是原始类型(例如整数或双精度),因此深复制与浅复制是没有意义的。但是如果存在引用属性,那么您必须依赖复制构造函数/工厂方法/克隆方法来执行您需要的那种复制。在每种情况下都需要对其进行编程。并且在一般情况下(必须处理循环)这很困难并且需要每个类实现特殊的方法。
还有另外一个潜在的复制对象数组的方法。如果数组中的对象是可序列化,然后你可以使用复制它们ObjectOutputStream
and ObjectInputStream
序列化然后反序列化数组。然而:
- 这个很贵,
- 它仅在对象可(传递地)序列化时才有效,并且
- 任何的值
transient
字段不会被复制。
不建议通过序列化进行复制。最好支持克隆或其他方法。
总而言之,在 Java 中最好避免深度复制。
最后,回答一下你的问题Position
类复制构造函数有效,我希望它是这样的:
public class Position {
private int x;
private int y;
...
public Position(Position other) {
this.x = other.x;
this.y = other.y;
}
...
}
正如@Turtle 所说,这并不涉及任何魔法。您(手动)实现一个构造函数,该构造函数通过从现有实例复制来初始化其状态。
1 - It is specified that the Object implementation of clone()
does a shallow copy, but this may be overridden. The javadoc for clone
specifies the "contract" as follows:
"Creates and returns a copy of this object. The precise meaning of "copy" may depend on the class of the object. The general intent is that, for any object x, the expression: x.clone() != x
will be true, and that the expression: x.clone().getClass() == x.getClass()
will be true, but these are not absolute requirements. While it is typically the case that: x.clone().equals(x)
will be true, this is not an absolute requirement."
Nothing in the "contract" talks about deep versus shallow copying. So if you are going to use clone
in this context, you need to know how the actual classes clone
method behaves.