【问题标题】:Why the interface references shows toString(), hashCode() and other Object’s method [duplicate]为什么接口引用显示 toString()、hashCode() 和其他 Object 的方法 [重复]
【发布时间】:2014-12-12 09:18:37
【问题描述】:

如果一个接口没有继承Object类,那么为什么接口引用了toString()、hashCode()等Object的方法。

【问题讨论】:

  • @JohanKarlsson 这个问题对我来说似乎很清楚——你不清楚哪一部分?

标签: java


【解决方案1】:

因为这就是语言的设计方式。任何实现接口的类肯定会有Object作为最终祖先,所以在执行时,这些方法肯定是可用的。

这是在JLS 9.2中指定的:

如果一个接口没有直接的超接口,则该接口隐式声明一个公共抽象成员方法m,签名为s,返回类型r,以及每个公共实例方法@987654327对应的throws子句t @ 带有签名 s、返回类型 r 和在 Object 中声明的 throws 子句 t,除非接口显式声明了具有相同签名、相同返回类型和兼容 throws 子句的抽象方法。

【讨论】:

  • 这是什么意思 "如果一个接口没有直接的超接口,那么该接口隐式声明了一个公共抽象成员方法m,签名为s,返回类型为r,并且throws 子句 t 对应于每个公共实例方法 m,签名为 s,返回类型为 r,并且在 Object 中声明了 throws 子句 t,除非接口显式声明了具有相同签名、相同返回类型和兼容 throws 子句的抽象方法。” 如果我使用 javap 反汇编该类,即使我不扩展任何超接口,它也只会显示显式方法?
  • @SalilVNair:从“我可以在接口类型的表达式上调用什么?”的角度来讨论接口的逻辑成员。
  • 谢谢 现在好像清楚了。
【解决方案2】:

在 Java 中,everythingObject 的子类,即使它没有明确声明是这样。所以你声明你的接口,然后任何实现你接口的类都必须是Object的子类,因为一切都是。

因为它是Object 的子类,所以它引入了Object 的所有可见方法,例如.toString()

【讨论】:

    【解决方案3】:

    接口的任何实现都必须扩展Object。例如:

    SomeInterface foo = new ConcreteImplementation();
    

    这里,ConcreteImplementation 必须扩展 Object,因为它是所有 Java 对象的最终祖先。因此,您可以通过您的foo 变量访问与Object 类关联的所有公共方法。

    【讨论】:

    • 但是 foo 变量是 SomeInterface 类型,并且没有其他未定义的方法在运行时可以访问,对吗?那么有没有对象的抽象方法是由JVM维护的呢?
    • @SalilVNair foo 变量指向ConcreteImplementation 类型的对象。您在 SomeInterface 变量中存储对它的引用这一事实无关紧要。
    猜你喜欢
    • 1970-01-01
    • 2019-06-24
    • 1970-01-01
    • 1970-01-01
    • 2020-07-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-01-17
    相关资源
    最近更新 更多