为什么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子句t在Object中声明,除非接口显式声明具有相同签名,相同返回类型和兼容throws子句的方法.
如§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)
输出可能因系统而异.