您已实现的是 浅表 副本。要实现 深度 复制,您必须进行更改
data[i] = other.data[i];
一些事情,分配一个 副本 的
other.data[i]到
data[i]。您如何执行此操作取决于
Position班级。可能的替代方法是:
- 复制构造函数:
data[i] = new Position(other.data[i]);
- 工厂方法:
data[i] = createPosition(other.data[i]);
- 克隆:
data[i] = (Position) other.data[i].clone();
笔记:
- 上面假设复制构造函数,工厂方法和克隆方法分别根据Position类实现“正确”的复制;见下文。
- 该
clone
方法只有在Position
明确支持的情况下才有效,并且通常被认为是次等解决方案。此外,您需要知道,clone
(即Object.clone()
方法)的本地实现会进行浅表复制。
实际上,在Java中实现深度复制的一般问题很复杂。在
Position类的情况下,将假定属性都是原始类型(例如int或double),因此,浅层复制与深层复制无关紧要。但是,如果有引用属性,则必须依靠复制构造函数/工厂方法/克隆方法来进行所需的复制。在每种情况下,都需要对其进行编程。在一般情况下(必须处理循环),这很困难,并且需要每个类实现特殊的方法。
还有另一种 可能的 方法可以复制对象数组。如果数组中的对象是可 序列化的
,则可以使用
ObjectOutputStream并
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所说的,没有任何魔术。您将实现一个构造函数(手动),该构造函数通过从现有实例复制来初始化其状态。



