从参数分配集合的首选方法是什么?

2024-01-28

我有这门课:

public MyClass {
    public void initialize(Collection<String> data) {
        this.data = data; // <-- Bad!
    }
    private Collection<String> data;
}

这显然是不好的风格,因为我引入了共享的可变状态。处理这个问题的首选方法是什么?

  • 忽略它?
  • 克隆集合?
  • ...?

EDIT:为了弄清楚为什么这很糟糕,想象一下:

MyClass myObject = new MyClass();
List<String> data = new ArrayList<String>();
myObject.initialize(data); // myObject.data.size() == 0
data.add("Test"); // myObject.data.size() == 1 

仅存储引用就提供了一种将数据注入私有字段的方法myObject.data,尽管它应该是完全私有的。

取决于性质MyClass这可能会产生严重影响。


最好的方法是深度克隆参数。出于性能原因,这通常是不可能的。最重要的是,并非所有对象都可以克隆,因此深度复制可能会引发异常并导致各种令人头痛的问题。

下一个最好的方法是“写时复制”克隆。 Java 运行时不支持此操作。

如果您认为有人可能会改变集合,请使用复制构造函数进行浅复制:

this.data = new HashSet<String> (data);

这将解决您的问题(因为 String 是不可变的),但是当集合中的类型可变时,它将失败。

另一个解决方案是,一旦将集合存储在某处,就始终使它们不可变:

Set<String> set = ...
...build the set...

// Freeze the set
set = Collections.unmodifiableSet(set);

// Now you can safely pass it elsewhere
obj.setData (set);

这里的想法是尽快将集合转变为“值对象”。任何想要更改集合的人都必须复制它、更改它,然后将其保存回来。

在类中,您可以保持集合可变并将其包装在 getter 中(无论如何您都应该这样做)。

这种方法的问题:性能(但可能没有你想象的那么糟糕)和纪律(如果你忘记在某个地方就会中断)。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

从参数分配集合的首选方法是什么? 的相关文章

随机推荐