• 请不要在回答技术问题时复制粘贴 AI 生成的内容
golangLover
V2EX  ›  程序员

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

  •  
  •   golangLover · Jul 23, 2021 via Android · 2611 views
    This topic created in 1779 days ago, the information mentioned may be changed or developed.

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

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

    谢谢

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

    这种问题不应该去 StackOverFlow 提问么?
    potatowish
        2
    potatowish  
       Jul 23, 2021 via iPhone
    很显然是后者,参考 JDK 源码 Arrays.asList
    kaneg
        3
    kaneg  
       Jul 23, 2021 via iPhone
    接口的行为应该是由文档定义的,而不是依赖具体的实现。
    再说用别人返回的 list 本来就是用来获取数据,调用 add 是不应该的,如果真的需要修改,应该自己新建。
    还有一种更好办法,就是用数组代替 list 。
    kidlj
        4
    kidlj  
       Jul 23, 2021
    返回的 interface 类型决定了调用者能够在返回值上应用的方法集合,如果一个操作超出了这个集合(比如 add ),那么就不应该返回这个 interface,而是用另一个 interface 或者具体类型替代。
    kidlj
        5
    kidlj  
       Jul 23, 2021
    补充一点:返回 interface 而不是具体类型的优势是,一是上边说的方法集合约定(只能调用这些方法),二是调用者不用关心 interface 包装的是哪个具体类型,只需调用 interface 定义的方法就能完成逻辑,而具体完成这个逻辑的还是被包装的具体类型,可能有多种实现。把 interface 看成一种抽象就好理解了。
    Leviathann
        6
    Leviathann  
       Jul 23, 2021
    理论上是标明 unmodifiable list 比较好
    但自从函数式思想传播开后,其实现在也很少会对 list 做增删改,都是用 stream 生成新的 list
    所以就偷懒写 list 了
    当然更好的方法是换一种对类型推导支持更加完善的语言,比如 kotlin
    chendy
        7
    chendy  
       Jul 24, 2021
    这事情只能怪 Java 的 List 接口做的不是很好,以及没有提供 不可变 List 这样的接口
    于是就只能全部 List 然后在文档里说明情况
    SoloCompany
        8
    SoloCompany  
       Jul 24, 2021
    你应该阅读一下 java1.2 时期的文档, 有详细说明 collection framework 的取舍, 其中就包含了引入 UnsupportedOperationException 而不是 Readonly collection 的讨论

    而现在你也可以选择 kotlin, kotlin List 就是 readonly 的, 所有的 collection interface 数量都 double 了成为配对的 Collection / MutableCollection
    golangLover
        9
    golangLover  
    OP
       Jul 24, 2021
    感谢上面的大哥,谢谢了
    Huelse
        10
    Huelse  
       Jul 25, 2021
    kotlin 或 scala,有 immutable data-structures
    About   ·   Help   ·   Advertise   ·   Blog   ·   API   ·   FAQ   ·   Solana   ·   879 Online   Highest 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 41ms · UTC 21:55 · PVG 05:55 · LAX 14:55 · JFK 17:55
    ♥ Do have faith in what you're doing.