10

为什么 JVM 规范声明接口必须有一个super_classof 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、返回类型为 r 和 throws 子句的公共实例方法 m在 Object 中声明,除非接口显式声明了具有相同签名、相同返回类型和兼容 throws 子句的方法。

4

2 回答 2

7

§9.2所述:

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

因此,我们看到,虽然没有直接超接口的接口没有显式扩展Object,但它仍然在Object内部具有与类的链接,因为编译器使用它来插入具有相同签名和返回类型的抽象方法以及 throws 子句。类中的公共方法Object,在接口内。这就是为什么对于一个接口,super_class 项的值必须始终是 constant_pool 表的有效索引。该索引处的 constant_pool 条目必须是表示类Object的 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. 上面的代码在我的系统上提供以下输出:

InterfaceTest@1ba34f2

输出可能因系统而异。

于 2013-04-27T18:02:54.223 回答
0

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

于 2013-04-27T18:22:46.880 回答