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

Phi*_*l K 10 java jvm jls

为什么JVM规范状态接口必须有一个super_classjava/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子句t在Object中声明,除非接口显式声明具有相同签名,相同返回类型和兼容throws子句的方法.

Vis*_*l K 7

§9.2中所述:

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

因此,我们看到,尽管没有直接超接口的接口没有显式扩展,Object但它仍然在Object内部具有类的链接,因为编译器使用它来插入具有相同签名和返回类型的抽象方法,并且抛出子句与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
    }
}
Run Code Online (Sandbox Code Playgroud)

上面的代码编译成功,即使toString()方法(其方法Object)未在其中声明MyInterface.上面的代码在我的系统上提供以下输出:

InterfaceTest@1ba34f2
Run Code Online (Sandbox Code Playgroud)

输出可能因系统而异.