例如我有一个 arraylist 要返回,那我在返回值写成 list,那我是能理解的。但如果我有一个 unmodifiable list 要返回,那我是不是应该直接写返回 unmodifiable list,还是写返回 list. 因为很多 impl 其实都只是实现了接口,但没有规定最终行为。要是我返回 list,调用者用 add method,不就有 UnsupportedOperationException ?
还是照样返回 list,但写注释来注明返回的是 unmodifiable list ?但这样也有不少负担。
谢谢
1
earneet 2021-07-23 19:06:44 +08:00
建议采用第二种方法。而且是很常见的做法。
一些接口,返回 list 的时候,我们都是采用复制一份 arraylist 的形式提供给调用者, 这样就避免了调用者的修改会对内部数据造成破坏。 unmodifiable list 自然更高效而且天生防止破坏。 最令我接受的是 Arrays.asList() 接口返回的是 List,且不支持修改操作。 类似的第一方接口还有不少。 这种问题不应该去 StackOverFlow 提问么? |
2
potatowish 2021-07-23 19:07:22 +08:00 via iPhone
很显然是后者,参考 JDK 源码 Arrays.asList
|
3
kaneg 2021-07-23 20:40:08 +08:00 via iPhone
接口的行为应该是由文档定义的,而不是依赖具体的实现。
再说用别人返回的 list 本来就是用来获取数据,调用 add 是不应该的,如果真的需要修改,应该自己新建。 还有一种更好办法,就是用数组代替 list 。 |
4
kidlj 2021-07-23 20:47:19 +08:00
返回的 interface 类型决定了调用者能够在返回值上应用的方法集合,如果一个操作超出了这个集合(比如 add ),那么就不应该返回这个 interface,而是用另一个 interface 或者具体类型替代。
|
5
kidlj 2021-07-23 20:52:35 +08:00
补充一点:返回 interface 而不是具体类型的优势是,一是上边说的方法集合约定(只能调用这些方法),二是调用者不用关心 interface 包装的是哪个具体类型,只需调用 interface 定义的方法就能完成逻辑,而具体完成这个逻辑的还是被包装的具体类型,可能有多种实现。把 interface 看成一种抽象就好理解了。
|
6
Leviathann 2021-07-23 22:00:17 +08:00
理论上是标明 unmodifiable list 比较好
但自从函数式思想传播开后,其实现在也很少会对 list 做增删改,都是用 stream 生成新的 list 所以就偷懒写 list 了 当然更好的方法是换一种对类型推导支持更加完善的语言,比如 kotlin |
7
chendy 2021-07-24 08:40:00 +08:00
这事情只能怪 Java 的 List 接口做的不是很好,以及没有提供 不可变 List 这样的接口
于是就只能全部 List 然后在文档里说明情况 |
8
SoloCompany 2021-07-24 13:05:13 +08:00
你应该阅读一下 java1.2 时期的文档, 有详细说明 collection framework 的取舍, 其中就包含了引入 UnsupportedOperationException 而不是 Readonly collection 的讨论
而现在你也可以选择 kotlin, kotlin List 就是 readonly 的, 所有的 collection interface 数量都 double 了成为配对的 Collection / MutableCollection |
9
golangLover OP 感谢上面的大哥,谢谢了
|
10
Huelse 2021-07-25 11:54:53 +08:00
kotlin 或 scala,有 immutable data-structures
|