java:传递数组的引用?

时间:2010-12-19 02:12:46

标签: java arrays oop

我有对象集合的数组,我将这个引用传递给方法,并且该方法将执行一些业务逻辑并更新对象,以便它将反映在原始对象中,因为我将它作为参考传递。现在我的问题是如何避免原始对象的更新。

如果涉及克隆,请告诉我上述案例需要做什么样的克隆

THX

4 个答案:

答案 0 :(得分:4)

你的情况有点棘手:

您有一组对象的引用。

Java总是按值传递,因此当您将对数组的引用传递给方法时,对数组的引用将按值传递。

因此该方法对调用范围具有相同数组的新引用。

您的问题的答案是:如果您不希望您的更改反映在对象中,则需要复制对象。所以,要通过它。

  1. 您有一组对象引用。
  2. 你想根据对象做一些工作,但你不想修改对象。
  3. 您应该创建一个对象数组 - 此数组中的对象是原始数组的副本。
  4. 通过'复制'我并不仅仅意味着对象复制=原创。您需要创建一个新的Object作为副本。在相关类上创建一个创建实例副本的getCopy()方法可能是个好主意。如果您的对象有孩子或者包含其他对象,这可能会很复杂。
  5. 您将副本数组传递给执行该操作的方法。

答案 1 :(得分:3)

如果希望原始对象保持不变,则需要对原始对象的副本进行更改。这意味着数组的“深层复制”,您不仅要创建第二个数组,引用相同的对象,还要复制数组中的每个对象。

根据谁应该拥有更改的对象(如果有人),您可以在调用者中创建此副本并将其传入,或者传入原始数组并让方法创建一组副本。第一个似乎更符合逻辑,但是在不了解你的设计的情况下很难说。

答案 2 :(得分:0)

您可以使用Collections.copy(dest, src)它会制作数组的深层副本。 但是,由于方法中的错误,你应该做一些技巧:

//Assuming, that src is an array

List<Integer> src2 = Arrays.asList(src)

List<Integer> dest = new ArrayList<Integer>(src2);

Collections.copy(dest, src2);

实际上,您不必传递源数组来构造destiantion数组。您必须传递与源数组大小相同的数组。

答案 3 :(得分:0)

有许多方法可以阻止方法更改作为参数传递的对象:

  • 制作对象的副本,然后传递副本。有多种方法可以复制对象。复制构造函数和静态工厂方法可能比实现clone()更好。
  • 为对象的类创建一个只读包装类,实例化它并传递它。只读包装器既不提供更新方法,也不实现它们什么也不做,或者抛出异常。
  • 重构对象的API,使其具有只读接口和读写接口,并将其作为前者的实例传递。 (当然,来电者可以尝试将其投射到后者......)
  • 使用Java安全性来防止不必要的更新。 (这很昂贵而且很复杂......)

当然,如果您试图“保护”的对象具有您希望阻止更改的深层结构,那么您需要确保处理此问题;例如通过深度复制,返回组件对象的副本或将它们包装回来等等。

上述大多数方法都会增加复杂性和运行时成本,因此我的建议是避免在需要的情况下进行设计。如果可行的话,只需将对象应该处理作为只读文档,并将其留给编码方法的人员的常识来做正确的事情。

例如,众所周知,您不应该以{{1​​}}中的键作为键的状态更改其值的更改。但是,通常不采取任何措施来试图“强制执行”这一点;即使用可变对象作为键......而不是改变它们。