2014-11-16 63 views
4

我讀過有關類構造函數here和問題隨之出現,爲什麼不以下層次結構是不正確:不一致的類層次結構

public class Test extends Subclass.Inner{ //compile-time error 
          //The hierarchy of the type Test is inconsistent 
    public Test() { 
     super(); 
    } 
} 


public class Subclass extends Test{ 
    public class Inner{ 
    } 
} 

正式

若父類的構造函數調用語句如果S是內部成員類,那麼它是編譯時錯誤,如果S是 而不是C聲明的詞法封閉類的成員或 繼承

我認爲這個例子完全符合我引用的規則。在​​的情況下,通過繼承是Test的詞彙插入類。爲什麼代碼不能正常工作?你能否提供一個反映這一點的適當例子?

回答

2

內部實例類(非靜態)實際上是轉化,像這樣:

public class Subclass extends Test { 
    public class Inner { 
    } 
} 

變得像這樣:

public class Subclass extends Test { 

} 

public class Inner { 
    Subclass parent; 
    public Inner(Subclass parent) { 
     this.parent = parent; 
    } 
} 

以下是有效的:

public class Container extends Subclass { 
    public class Test extends Subclass.Inner { 
     public Test() { 
      super(); 
     } 
    } 
} 

public class Subclass { 
    public class Inner { 
    } 
} 
2

的內部類的實例必須有一個封閉實例,它在內部類實例之前被初始化。另一方面,超類構造函數總是在子類構造函數之前執行。因此,創建​​的實例需要首先調用Test的構造函數,該構造函數需要先調用SubClass.Inner的構造函數,但SubClass.Inner無法在其包含實例之前進行初始化。

我相信爲了滿足你引用的條件,超類Inner必須被一個超類Test包圍。在你的情況下,它被測試的子類包圍。

1

這裏是你缺少一個條款(8.4.1):如果T被C的extendsimplements子句中提及無論是作爲一個超類或超直接取決於類型T

C類,或作爲超類或超級界面名稱的限定詞。

C類取決於上如果任一以下的條件成立的基準型T:

  • Ç直接取決於一類d依賴於T(使用該定義遞歸地)。

如果一個類依賴於它自己,那是編譯時錯誤。

這是一個編譯時錯誤,因爲聲明的Subclass的超包含Subclass作爲預選賽超類名的。

這是除了極端怪異的循環定義,你有去這裏。 Test本身就是一個外部範圍。

這不編譯任,但它並不像內部類是不解:

class Test implements Test.ITest { 
    interface ITest {} 
} 

Netbeans的給了我一個更簡單的錯誤,有「循環產業」。類聲明不允許以這種方式引用它自己。