2013-04-27 60 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指定的行爲的具體實現 - 就像類實現接口並具有實現細節一樣。