为什么接口根据类文件格式扩展Object?

时间:2013-04-27 17:39:08

标签: java jvm jls

为什么JVM规范声明接口必须具有super_class java/lang/Object,即使接口不扩展java/lang/Object

我特指的是JVM规范的§4.1,其中包含:

  

对于接口,super_class项的值必须始终是constant_pool表的有效索引。该索引处的constant_pool条目必须是表示Object类的CONSTANT_Class_info结构。

在JLS的§9.2中,它表示接口不扩展Object。而是声明一个隐式创建的抽象方法,该方法匹配Object类中的每个公共方法:

  

如果接口没有直接的超接口,那么接口隐式声明一个公共抽象成员方法m,其中包含签名s,返回类型r和throws子句t,对应于具有签名s的每个公共实例方法m,返回类型为r, throws在Object中声明的子句t,除非接口显式声明具有相同签名,相同返回类型和兼容throws子句的方法。

2 个答案:

答案 0 :(得分:7)

§9.2中所述:

  

如果接口没有直接的超级接口,那么接口   隐式声明带有签名的公共抽象成员方法m   s,返回类型r,以及对应于每个公共的throws子句t   具有签名s的实例方法m,返回类型r和throws子句t   在Object中声明,除非具有相同签名的方法相同   返回类型,并且显式声明了兼容的throws子句   界面。

因此,我们看到,尽管没有直接超接口的接口没有显式扩展Object,但它内部仍然有一个Object类的链接,因为编译器使用它来插入抽象具有相同签名和返回类型以及throws子句的方法,与接口内Object类中的公共方法相同。这就是为什么对于接口,super_class项的值必须始终是constant_pool表的有效索引。该索引处的constant_pool条目必须是表示类 Object 的CONSTANT_Class_info结构。这就是接口引用变量可以成功调用公共实例方法的原因,例如toString()的{​​{1}}方法。例如,考虑下面给出的代码:

Object

即使在interface MyInterface {} public class InterfaceTest implements MyInterface { public static void main(String[] args) { MyInterface mInterface = new InterfaceTest(); System.out.println(mInterface.toString());//Compiles successfully. Although toString() is not declared within MyInterface } } 内未声明toString()方法(Object的方法),上述代码也能成功编译。上面的代码在我的系统上提供以下输出:

MyInterface

输出可能因系统而异。

答案 1 :(得分:0)

您在JVM规范中看到的基本上是JLS指定的行为的具体实现 - 就像类实现接口并具有实现细节一样。