使用Java中的getter方法返回私有集合 [英] Returning a private collection using a getter method in Java

查看:130
本文介绍了使用Java中的getter方法返回私有集合的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有许多在内部使用私有集或列表的Java类。我希望能够使用get ... List()方法返回这些集合/列表。

I have a number of Java classes that use private sets or lists internally. I want to be able to return these sets/lists using a get...List() method.

我正在考虑的替代方案:

The alternatives I am considering:


  1. 返回对内部对象的引用

  2. 构造一个新的集合/列表并填写它(这看起来很糟糕吗?)

  3. 使用 Collections.unmodifiableList(分区);

  1. return a reference to the internal object
  2. construct a new set/list and fill it up (this seems bad practice?)
  3. use Collections.unmodifiableList(partitions);

这些是解决这个问题最常见/最好的方法之一?

Which of these is the most common / best way to solve this issue?

推荐答案

有很多方面要做考虑一下正如其他人已经指出的那样,最终的决定取决于你的意图,但是关于这三个选项的一些一般性陈述:

There are many aspects to consider here. As others already have pointed out, the final decision depends on what your intention is, but some general statements regarding the three options:

1。返回对内部对象的引用

这可能会带来问题。当你这样做时,你几乎不可能保证一致的状态。来电者可能会获得该列表,然后做一些讨厌的事情

This may impose problems. You can hardly ever guarantee a consistent state when you are doing this. The caller might obtain the list, and then do nasty things

List<Element> list = object.getList();
list.clear();
list.add(null);
...

可能没有恶意的意图但是不小心,因为他假设安全/允许这样做。

Maybe not with a malicious intention but accidentally, because he assumed that it was safe/allowed to do this.

2。构建一个新的集合/列表并填写它(这似乎是不好的做法?)

这不是一般的坏习惯。无论如何,它是API设计方面迄今为止最安全的解决方案。这里唯一需要注意的是,可能存在性能损失,具体取决于几个因素。例如。列表中包含多少个元素,以及如何使用返回的列表。一些(可疑的?)模式,如此一个

This is not a "bad practice" in general. In any case, it's by far the safest solution in terms of API design. The only caveat here may be that there might be a performance penalty, depending on several factors. E.g. how many elements are contained in the list, and how the returned list is used. Some (questionable?) patterns like this one

for (int i=0; i<object.getList().size(); i++)
{
    Element element = object.getList().get(i);
    ...
}

可能会变得非常昂贵(尽管有人可能会争辩无论是在这种特殊情况下,用户的错误都是这样实现的,一般问题仍然有效)

might become prohibitively expensive (although one could argue whether in this particular case, it was the fault of the user who implemented it like that, the general issue remains valid)

3。使用Collections.unmodifiableList(分区);

这是我个人经常使用的。它在API设计意义上是安全的,与复制列表相比,其开销只有微不足道。但是,调用者在获得对它的引用之后知道该列表是否可能发生变化是很重要的。

This is what I personally use rather often. It's safe in the sense of API design, and involves only a negligible overhead compared to copying the list. However, it's important for the caller to know whether this list may change after he obtained a reference to it.

这导致......

文档该方法正在做什么!不要写这样的评论

Document what the method is doing! Don't write a comment like this

/** 
 * Returns the list of elements.
 *
 * @return The list of elements. 
 */
public List<Element> getList() { ... }

相反,请指定您可以确定列表的内容。例如

Instead, specify what you can make sure about the list. For example

/** 
 * Returns a copy of the list of elements...
 */

/** 
 * Returns an unmodifiable view on the list of elements...
 */






就我个人而言,我总是在两种选择之间徘徊:


Personally, I'm always torn between the two options that one has for this sort of documentation:


  • 明确方法正在做什么

  • 不要暴露或过度指定实施细节

所以,例如,我经常写这样的文档:

So for example, I'm frequently writing documentations like this one:

/** 
 * Returns an unmodifiable view on the list of elements. 
 * Changes in this object will be visible in the returned list. 
 */

第二句是清晰的绑定关于行为的陈述。调用者知道这一点重要。对于并发应用程序(并且大多数应用程序以某种方式并发),这意味着调用者假设列表可能在获得后同时更改引用,当迭代列表时发生更改时,可能会导致 ConcurrentModificationException

The second sentence is a clear and binding statement about the behavior. It's important for the caller to know that. For a concurrent application (and most applications are concurrent in one way or the other), this means that the caller has to assume that the list may change concurrently after he obtained the reference, which may lead to a ConcurrentModificationException when the change happens while he is iterating over the list.

但是,这些详细的规范限制了之后改变实施的可能性。如果您以后决定返回内部列表的副本,则行为将以不兼容的方式更改。

However, such detailed specifications limit the possibilities for changing the implementation afterwards. If you later decide to return a copy of the internal list, then the behavior will change in an incompatible way.

所以有时我也明确指出没有指定行为:

So sometimes I also explicitly specify that the behavior is not specified:

/** 
 * 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...
 */

当您打算创建公共API时,这些问题主要起因很重要。一旦您以某种方式实现它,人们将以一种或另一种方式依赖行为。

These questions are mainly imporant when you intent do create a public API. Once you have implemented it in one way or another, people will rely on the behavior in one or the other way.

所以回到第一点:它总是取决于你想要达到的目标。

So coming back to the first point: It always depends on what you want to achieve.

这篇关于使用Java中的getter方法返回私有集合的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆