V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
V2EX 提问指南
wuyukai
V2EX  ›  问与答

[ Java ] [IDEA Bug?] List 接口中 boolean add(E) 方法到底是由覆盖了 Collection 接口而来,还是继承自 Collection 接口而来?

  •  
  •   wuyukai · 2017-06-09 17:13:31 +08:00 · 2638 次点击
    这是一个创建于 2754 天前的主题,其中的信息可能已经有所发展或是发生改变。

    如图,用 IDEA 左栏的 Structure 方式查看 List 接口的结构。

    如下显示,上半部分表示覆盖了 Collection 接口的方法,标注出来的有 add 和 addAll 方法。下半部份表示继承自 Collection 接口的方法,标注出来的也是 add 和 addAll 方法。

    20170609149699852298149.jpg

    那么问题来了

    这其中显示覆盖关系或继承关系。两个 add 和两个 addAll 的签名都是一样的,那按我目前知识可以理解的就是签名一样,这 List 接口中的方法必然是由覆盖 Collection 接口得到的啊,那么 IDEA 中显示的这个继承关系又是怎么一回事呢?这是 IDEA 中的问题吗?还是说这里面有隐藏的知识点,我没理解到位??

    同时我也用反射打印了 List 中所有层级的方法的 log

    也并未发现这个继承关系的方法藏在何处。 20170609149699942975957.png

    请大家讨论、指点,多谢。

    8 条回复    2017-06-10 00:06:57 +08:00
    0915240
        1
    0915240  
       2017-06-09 18:01:35 +08:00 via iPhone
    你这是哪个版本的?
    raptium
        2
    raptium  
       2017-06-09 18:12:18 +08:00 via iPhone
    下面不是灰的吗 它的意思是不是被 override 了
    wwqgtxx
        3
    wwqgtxx  
       2017-06-09 20:00:36 +08:00   ❤️ 1
    意思在于你看看代码,Collection 这个接口定义了 add 这个 method,而 List 这个接口也定义了 add 这个 method,而且还是在文件中重新定义了一遍(虽然方法签名都一样)
    wwqgtxx
        4
    wwqgtxx  
       2017-06-09 20:12:00 +08:00
    而且他们的 javadoc 部分 @throws 不一样,所以 idea 可能把他们当成了不同的方法看待了吧
    wuyukai
        5
    wuyukai  
    OP
       2017-06-09 20:15:20 +08:00 via Android
    @0915240 jdk 1.8,idea 2007.1
    wuyukai
        6
    wuyukai  
    OP
       2017-06-09 20:17:16 +08:00 via Android
    @raptium 上面是表示被覆盖,如果下面表示被覆盖的话不会仅仅只显示这两个方法,collection 中的所有方法应该都显示
    wuyukai
        7
    wuyukai  
    OP
       2017-06-09 20:54:08 +08:00
    @wwqgtxx 子接口中包含的父接口中相同的方法,这么做了在机制中就是方法覆盖,而不是重新定义。如图在 IDEA 中显示的 List 中 add 方法实为 Override Collection。

    ![20170609149701135166466.png]( http://ofrdtlim5.bkt.clouddn.com/20170609149701135166466.png)
    确实在 javadoc 中异常的指定不一样,但是 javadoc 始终只是 javadoc,它是被注释的东西,无法对代码产生影响。所以我觉得这两个方法本身设计者是想让他们有所不同的,但是又要保证签名相同在 Java 语法上就没办法做到这一点限制,只能通过 javadoc 的方式来指定这两个的区别,在实现的时候按照指定的 javadoc 来实现,以下是我找到的网上的感觉说的合意的答案。List 中的 add 仅相当于是接口描述上的更加具体吧。
    ────────────────────────
    其实只是定义的接口行为不一样。
    表示子类如果实现 List 接口,那就需要遵循 List Javadoc 的行为。
    如果实现 Collection 那就必须要遵循 Collection Javadoc 的行为。
    不单单只是重写一个方法而已,重写这个方法的时候应该按照 Javadoc 所描述的一样。这样才正确。
    SoloCompany
        8
    SoloCompany  
       2017-06-10 00:06:57 +08:00
    你可以觉得是一个 bug,但我觉得是 JetBrains 是故意的,因为这两个方法签名虽然是完全 override 了,但由于在定义具体化了很多,IDEA 把它等同于另一种形式的覆盖

    比如
    父类 Base getXXX()
    子类 Extend getXXX()

    他们的签名不完全一致,但会导致 override,在 Java 1.4 以及之前这种 override 是不允许的
    在 1.5 之后开始允许,编译器会给子类自动生成一个 override 的 Base getXXX() 的方法,自动 delegate 给 Extend 后的版本

    感觉 IDEA 是模拟为这种情况来生成语法结构,毕竟两个 add 方法的定义实际是不一样的
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   3133 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 25ms · UTC 12:46 · PVG 20:46 · LAX 04:46 · JFK 07:46
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.