为什么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子句的方法。
答案 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指定的行为的具体实现 - 就像类实现接口并具有实现细节一样。