1
6
当一个对象返回一个可变的私有字段时,它将暴露于外部代理对其内部状态的不需要的/未知的更改,这违反了封装。 你所指的模式,叫做 安全发布 如果是注释掉的代码:
它正在创建一个新的对象,但它只是列表顶部的一个很薄的层,您几乎无法测量这样做的cpu或内存性能成本。 您还可以:
|
2
7
来自波希米亚的答案陈述了一些关于返回不可修改、不可变或防御复制的数据以保留封装的好的一般原则。如果数据是对象的内部数据,例如存储在字段中,那么这肯定是正确的。 但是,OP声明每次调用方法时都会新建返回的列表。在这种情况下,为什么返回一个不可修改的列表而不是一个常规的ArrayList?这是有原因的,但它们有点微妙,而且它们与封装的关系不大,因为封装可以保持实现的灵活性。 作为一个背景主题,您需要决定这个API是否有任何长期的兼容性约束或策略。如果你返回一个可变列表,那么它是可能的(根据 Hyrum's Law )调用者将依赖于它的易变性。(Hyrum定律本质上说,系统的任何可观察属性最终都将取决于用户。)我个人认为,修改返回给您的集合是草率的编程,但事实是,人们会这样做。如果是这样的话,将来你会建议将返回的列表更改为不可修改的,这会被禁止吗,因为它是不兼容的,并且会打断一些调用方?如果你不在乎兼容性(而有些项目不在乎),那么也许这无关紧要。但是如果你这样做了,那么你应该考虑现在返回一个不可修改的列表。 一个原因(其他人在评论中提到)是,您可能决定不每次都创建一个新列表,但您可能会将其缓存并返回给多个调用方。如果您这样做,它绝对应该是不可修改的,以防止一个调用者修改列表并影响所有调用者。
另一个原因是不同的列表实现具有不同的性能和空间特性。这个
您可能还希望向该方法添加一些自适应行为,例如,取决于返回列表中的元素数。例如,
如果不将ArrayList包装在一个不可修改的包装器中,调用方将暴露于行为上的奇怪差异,例如列表有时是可修改的,有时不是。如果可能,最好在所有情况下提供统一的行为,从而为将来的更改保留实现灵活性。 |
Giffyguy · 如何限制在构造向量后调用'resize()'? 2 年前 |
vytaute · 返回表类型时Oracle函数中的类型错误 2 年前 |
bbgghh · 在scala中连接两个列表时如何处理不匹配的键 2 年前 |
dev-chicco · Laravel系列寻找常见物品 2 年前 |
Mitch · Laravel-雄辩的单品合并系列 6 年前 |
Kieran · 为什么类X可以从集合继承<X> 6 年前 |
John · 如何在不返回集合本身的情况下返回集合的数据? 6 年前 |
Niklas Mertsch · 在泛型集合中实现移除(对象o) 6 年前 |