V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
golangLover
V2EX  ›  程序员

对于面向接口的行为不太明白

  •  
  •   golangLover · 2021-07-23 18:53:17 +08:00 via Android · 2027 次点击
    这是一个创建于 1000 天前的主题,其中的信息可能已经有所发展或是发生改变。

    例如我有一个 arraylist 要返回,那我在返回值写成 list,那我是能理解的。但如果我有一个 unmodifiable list 要返回,那我是不是应该直接写返回 unmodifiable list,还是写返回 list. 因为很多 impl 其实都只是实现了接口,但没有规定最终行为。要是我返回 list,调用者用 add method,不就有 UnsupportedOperationException ?

    还是照样返回 list,但写注释来注明返回的是 unmodifiable list ?但这样也有不少负担。

    谢谢

    10 条回复    2021-07-25 11:54:53 +08:00
    earneet
        1
    earneet  
       2021-07-23 19:06:44 +08:00
    建议采用第二种方法。而且是很常见的做法。
    一些接口,返回 list 的时候,我们都是采用复制一份 arraylist 的形式提供给调用者, 这样就避免了调用者的修改会对内部数据造成破坏。
    unmodifiable list 自然更高效而且天生防止破坏。
    最令我接受的是 Arrays.asList() 接口返回的是 List,且不支持修改操作。 类似的第一方接口还有不少。

    这种问题不应该去 StackOverFlow 提问么?
    potatowish
        2
    potatowish  
       2021-07-23 19:07:22 +08:00 via iPhone
    很显然是后者,参考 JDK 源码 Arrays.asList
    kaneg
        3
    kaneg  
       2021-07-23 20:40:08 +08:00 via iPhone
    接口的行为应该是由文档定义的,而不是依赖具体的实现。
    再说用别人返回的 list 本来就是用来获取数据,调用 add 是不应该的,如果真的需要修改,应该自己新建。
    还有一种更好办法,就是用数组代替 list 。
    kidlj
        4
    kidlj  
       2021-07-23 20:47:19 +08:00
    返回的 interface 类型决定了调用者能够在返回值上应用的方法集合,如果一个操作超出了这个集合(比如 add ),那么就不应该返回这个 interface,而是用另一个 interface 或者具体类型替代。
    kidlj
        5
    kidlj  
       2021-07-23 20:52:35 +08:00
    补充一点:返回 interface 而不是具体类型的优势是,一是上边说的方法集合约定(只能调用这些方法),二是调用者不用关心 interface 包装的是哪个具体类型,只需调用 interface 定义的方法就能完成逻辑,而具体完成这个逻辑的还是被包装的具体类型,可能有多种实现。把 interface 看成一种抽象就好理解了。
    Leviathann
        6
    Leviathann  
       2021-07-23 22:00:17 +08:00
    理论上是标明 unmodifiable list 比较好
    但自从函数式思想传播开后,其实现在也很少会对 list 做增删改,都是用 stream 生成新的 list
    所以就偷懒写 list 了
    当然更好的方法是换一种对类型推导支持更加完善的语言,比如 kotlin
    chendy
        7
    chendy  
       2021-07-24 08:40:00 +08:00
    这事情只能怪 Java 的 List 接口做的不是很好,以及没有提供 不可变 List 这样的接口
    于是就只能全部 List 然后在文档里说明情况
    SoloCompany
        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
    golangLover
        9
    golangLover  
    OP
       2021-07-24 23:42:52 +08:00
    感谢上面的大哥,谢谢了
    Huelse
        10
    Huelse  
       2021-07-25 11:54:53 +08:00
    kotlin 或 scala,有 immutable data-structures
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   我们的愿景   ·   实用小工具   ·   3058 人在线   最高记录 6543   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 29ms · UTC 00:18 · PVG 08:18 · LAX 17:18 · JFK 20:18
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.