2013-04-27 18 views
10

为什么JVM规范声明接口必须有super_classjava/lang/Object,即使接口不能扩展java/lang/Object接口为什么根据类文件格式扩展Object?

我专门指的是JVM规范,它说的§4.1

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

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

如果接口有没有直接的超级,则接口隐式声明与签名s,返回类型为r的公共抽象成员方法M ,并且抛出与每个公共实例方法m对应的子句t与签名s,返回类型r并抛出在Object中声明的子句t,除非具有相同签名,相同返回类型和兼容throws子句的方法由接口。

回答

7

§9.2提到:

如果接口没有直接超接口,则接口 隐式声明与签名 S,返回类型为r的公共抽象成员方法米,和throws子句吨对应于每个公有 实例方法m带签名s,返回类型r,并抛出在Object中声明的子句t ,除非具有相同签名的方法,返回类型相同的 以及兼容的throws子句由明确声明3210的接口。

因此,我们看到,虽然没有直接的超接口,接口不明确扩展Object但仍然有内部Object类的链接,因为它是由编译器使用插入具有相同签名和抽象方法返回类型并抛出子句作为Object类中公共方法的子句。这就是为什么对于接口,super_class项的值必须始终是constant_pool表中的有效索引。该索引处的constant_pool条目必须是代表类对象的CONSTANT_Class_info结构。这就是接口引用变量可以成功调用公共实例方法的原因,例如toString()方法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未声明。以上代码在我的系统上提供以下输出:

[email protected] 

输出可能因系统而异。

0

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