番石榴不可变的集合有用还是只是额外的开销?

时间:2016-03-14 22:32:57

标签: java guava immutability

我正在查看一些源代码,它似乎几乎无处不在地使用Guava的不可变集合。现在,这个应用程序不是多线程的,因此并发性并不是一个问题。

我正在看番石榴的github wiki并且它说 - 当你不期望修改一个系列,或者期望一个系列保持不变时,这是一个很好的做法来防御性地复制它成为一个不可变的集合。

现在我的问题是 - 即使它们没有外部公开并在应用程序内部使用,或者在这种情况下是不必要的额外开销,制作这些集合的防御性副本是一个好主意吗?我很好奇。

1 个答案:

答案 0 :(得分:3)

如果你的班级被传递了一个它所存储的集合,那么无论如何都要采取防御性的副本。通过这种方式,它可以与外部世界分离,你可以肯定地推理你的课程,未来对外界的改变不会破坏你的课程的假设(比如,如果集合在传递给构造函数后被外部修改)。请参阅有效的Java项目39。

由于您的默认姿势应该是防御性复制,因此只要有意义,使该副本不可变是非常有用的。这会立即告诉读者有关该集合的更多信息:其内容永远不会改变。这也意味着你不需要在getter-methods中防御性地复制 out :只需直接返回不可变集合。这也为您的班级用户提供了更多信息。

此外,如果你传递给你的类的集合恰好是兼容的Immutable类型,那么Guava很聪明,并且实际不会复制。因此,通过广泛接受不变性,您最终会获得防御性复制的所有好处,几乎没有任何成本。

提示:请参阅ImmutableCollection javadoc,了解有关申报内容的地点和原因的建议,例如: ImmutableList vs List