我想使用构造函数对对象数组进行深层复制。
public class PositionList {
private Position[] data = new Position[0];
public PositionList(PositionList other, boolean deepCopy) {
if (deepCopy){
size=other.getSize();
data=new Position[other.data.length];
for (int i=0;i<data.length;i++){
data[i]=other.data[i];
}
然而,由于某种原因,我上面所说的不起作用。我有运行的自动化测试,并且它没有通过这些测试。所以这里有一个错误,我不确定它是什么。
答案 0 :(得分:23)
您实施的是浅副本。要实施深副本,您必须这样做 变化
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();
注意:
clone
方法仅在Position
明确支持时才有效,这通常被视为劣质解决方案。此外,您需要注意clone
的本机实现(即Object.clone()
方法)执行浅层复制。实际上,在Java中实现深度复制的一般问题很复杂。在Position
类的情况下,可以假设属性都是基本类型(例如,整数或双精度),因此深度与浅度复制是没有实际意义的。但是,如果存在引用属性,则必须依赖复制构造函数/工厂方法/克隆方法来执行所需的复制。在每种情况下都需要编程。在一般情况下(你必须处理周期),这很困难,并要求每个类实现特殊的方法。
还有一种潜在的方法可以复制对象数组。如果数组中的对象是 serializable ,则可以使用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所说,没有任何魔法可言。您可以实现一个构造函数(手动),通过从现有实例复制来初始化其状态。
答案 1 :(得分:2)
当你说:
data[i]=other.data[i];
您只是复制引用列表(假设这是一个对象数组)。如果要进行深层复制,则需要使用new
为数组中的每个对象创建一个新实例。
答案 2 :(得分:1)
而不是说:
data[i]=other.data[i]
您需要为Position
创建一个复制构造函数(换句话说,一个构造函数,用于接收另一个Position
并复制其中的原始数据)并说出data[i]=new Position(other.data[i]);
基本上你的“深层复制”构造函数PositionList
是一个复制构造函数,虽然复制构造函数确实倾向于指示深层复制,因此deepCopy
参数是不必要的。
答案 3 :(得分:0)
这是我使用的功能:
Option Explicit
Public Sub Tabtest()
Dim objIE As InternetExplorer
Set objIE = CreateObject("InternetExplorer.Application")
With objIE
.Top = 0
.Left = 0
.Width = 800
.Height = 600
.AddressBar = 1
.StatusBar = 1
.Toolbar = 1
.Visible = True
.navigate "https://www.google.com/search?q=NYSE:WSO&tbm=fin#scso=uid_H2LSWorGEpD3gQaCt5uQBg_5:0,uid_bmLSWpGcLOLbgAbIzILQDw_5:0&wptab=OVERVIEW"
While .Busy = True Or .readyState < 4: DoEvents: Wend
.document.getElementsByClassName("SVWlSe")(1).Click
While .Busy = True Or .readyState < 4: DoEvents: Wend
.document.getElementsByClassName("dbsr")(0).getElementsByTagName("a")(0).Click
End With
End Sub
它仅适用于具有单个级别的对象的数组。
答案 4 :(得分:-3)
这应该是一个深刻的&#34;复制
int [] numbers = { 2, 3, 4, 5};
int [] numbersClone = (int[])numbers.clone();