2013-02-07 75 views
2

我正在研究一个保存和调用屏幕状态的系统,这是我第一次搞这样的东西,所以我不确定最好的东西有关这方面的方法是,但我现在将所有“PreviewMonitor”对象(大约40左右)存储在数组列表中。问题是,当我创建一个名为“allPreviewMonitors”的ArrayList的副本时,我最终得到一个ArrayList,其元素在更新原始元素时不断变化。这几乎就好像我正在处理原始的ArrayList,事实上,当我创建allPreviewMonitors的副本时,它应该是一个完全不同的ArrayList,其中包含元素及其状态的“冻结”版本。为什么会发生这种行为?如果需要,我可以显示代码,但我不确定这是否需要。ArrayList的副本不断修改为原始的值

回答

2

您只是将对象引用复制到ArrayList中。你需要自己复制对象。

在Java中,所有对象变量实际上都是引用变量。因此,代码:

Myclass myObject = new Myclass(); 
Myclass otherObject = myObject; 

创建一个对象MYCLASS并存储在参考变量myObject该MYCLASS对象的引用。然后它创建一个新的参考变量otherObject,并将参考数据(例如存储器地址)从myObject复制到otherObject。这些现在指的是内存中的同一个对象。在这一点上,该行

myObject.myMethod(); 

有你在你的ArrayList中获得什么相同的结果

otherObject.myMethod(); 

是同一对象的不同引用。 你想要的是下列之一:

Myclass otherObject = myObject.clone(); // use the clone function 
// OR 
Myclass otherObject = new Myclass(myObject); // use a copy constructor 

如果你把你的对象为使用clone()或拷贝构造函数,你的ArrayList将包含,以相同的拷贝引用,而不是引用相同的副本ArrayList中。

正如其他人所指出的那样,只是把引用的副本被称为“浅拷贝”,同时使被称为被称为“深拷贝”

+1

我试过使用复制构造函数,但是这导致了相同的输出。难道是因为PreviewMonitor(我的对象)包含一个JButton对象,这正是我使用PreviewMonitor.getJButton()拉对象? –

+0

我也尝试过以上的方法,但是当我修改克隆对象时,它也会反映到原来的一个,也不知道出了什么问题。 –

4

一个Arraylist像所有Collections,只包含对象的引用。 仅复制列表是不够的,您还必须在创建列表的副本时克隆()元素(或创建新元素,或使用复制构造函数)。

这称为制作“深度复制”,而您目前有一个“浅复制”。

+0

对象的副本究竟是如何去有关“克隆”PreviewMonitor对象。我认为这可能是问题,所以我创建了一些东西来测试它,并在PreviewMonitor对象中创建了一个“克隆”方法,因为我认为它应该创建,但我不太确定如果我做对了。 public PreviewMonitor clone(){return this; } –

2

您需要确保您执行“深度复制” - 即克隆PreviewMonitor对象。默认情况下,你只需做一个浅拷贝并复制对同一个对象的引用。

+0

我如何去“克隆”PreviewMonitor对象。我认为这可能是问题,所以我创建了一些东西来测试它,并在PreviewMonitor对象中创建了一个“克隆”方法,因为我认为它应该创建,但我不太确定如果我做对了。 \t public PreviewMonitor clone(){ \t \t return this; \t} –

+0

我假设'PreviewMonitor'是你自己的对象之一。克隆过程取决于对象。你通常会调用clone()方法。有更多信息在http://en.wikipedia.org/wiki/Clone_(Java_method)。 – Andrew

0

要克隆,您不能只返回当前对象。您必须创建一个与当前对象具有相同值的新对象。换句话说,使用当前对象的类的构造函数并创建一个新对象。确保旧对象和新对象之间的属性匹配。返回新对象并重复原始列表中的每个对象。

+0

我已经试过both'code” \t \t为(PreviewMonitor sourcePreviewMonitor:previewMonitors){ \t \t \t this.previewMonitors.add(新PreviewMonitor(sourcePreviewMonitor.getPos(),sourcePreviewMonitor.getJButton()的getX(),sourcePreviewMonitor.getJButton。 () \t \t \t \t \t .getY(),sourcePreviewMonitor.getJButton()。的getWidth(),sourcePreviewMonitor.getJButton()。的getHeight(),sourcePreviewMonitor.getColumn(), \t \t \t \t \t sourcePreviewMonitor.getRow() ,sourcePreviewMonitor.getRight())); \t \t} - 然后为PreviewMonitor对象创建一个新的构造函数,使其获得一个参数,另一个PreviewMonitor并将其传入。 –

相关问题