我有许多在内部使用私有(private)集或列表的 Java 类。我希望能够使用 get...List() 方法返回这些集合/列表。
我正在考虑的备选方案:
- 返回对内部对象的引用
- 构建一个新的集合/列表并填充它(这似乎是不好的做法?)
- 使用
Collections.unmodifiableList(partitions);
以下哪一个是解决此问题的最常见/最佳方法?
最佳答案
这里有很多方面需要考虑。正如其他人已经指出的那样,最终决定取决于您的意图,但关于这三个选项的一些一般性陈述:
<强>1。返回对内部对象的引用
这可能会带来问题。执行此操作时,您几乎无法保证状态一致。调用者可能会获取列表,然后做一些下流的事情
List<Element> list = object.getList();
list.clear();
list.add(null);
...
也许不是出于恶意意图,而是意外,因为他假设这样做是安全的/允许的。
<强>2。构造一个新的集合/列表并填充它(这似乎是不好的做法?)
这不是一般的“坏习惯”。无论如何,就 API 设计而言,它是迄今为止最安全的解决方案。此处唯一需要注意的是,可能会出现性能损失,具体取决于多种因素。例如。列表中包含多少元素,以及如何使用返回的列表。像这样的一些(有疑问的?)模式
for (int i=0; i<object.getList().size(); i++)
{
Element element = object.getList().get(i);
...
}
可能会变得非常昂贵(尽管有人可能会争论在这种特殊情况下是否是 user 那样实现它的错误,general 问题仍然有效)
<强>3。使用 Collections.unmodifiableList(partitions);
这是我个人经常使用的。它在 API 设计的意义上是安全的,并且与复制列表相比只涉及微不足道的开销。然而,对于调用者来说,重要的是要知道在他获得对它的引用之后这个列表是否会改变。
这导致...
最重要的建议:
记录方法在做什么!不要写这样的评论
/**
* Returns the list of elements.
*
* @return The list of elements.
*/
public List<Element> getList() { ... }
相反,指定您可以确定的列表。例如
/**
* Returns a copy of the list of elements...
*/
或
/**
* Returns an unmodifiable view on the list of elements...
*/
就个人而言,对于此类文档,我总是在两种选择之间左右为难:
- 明确该方法在做什么以及如何可以使用
- 不要公开或过度指定实现细节
例如,我经常编写这样的文档:
/**
* Returns an unmodifiable view on the list of elements.
* Changes in this object will be visible in the returned list.
*/
第二句是关于行为的清晰且有约束力的陈述。调用者知道这一点重要。对于并发应用程序(大多数应用程序都是以一种或另一种方式并发的),这意味着调用者必须假设在他获得引用,这可能会导致 ConcurrentModificationException
当他遍历列表时发生更改。
但是,如此详细的规范限制了之后更改实现的可能性。如果您稍后决定返回内部列表的副本,那么行为将以不兼容的方式发生变化。
所以有时候我也明确的指定行为不指定:
/**
* Returns an unmodifiable list of elements. It is unspecified whether
* changes in this object will be visible in the returned list. If you
* want to be informed about changes, you may attach a listener to this
* object using this-and-that method...
*/
当您打算创建公共(public) API 时,这些问题非常重要。一旦您以一种或另一种方式实现它,人们就会依赖以这种或另一种方式的行为。
所以回到第一点:这始终取决于您想要实现的目标。
关于java - 在 Java 中使用 getter 方法返回私有(private)集合,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23607881/