2013-10-06 91 views
1

讓我們有下面的類:通用構造

public class MyClass<T>{ 
    public <E> MyClass(E e){ System.out.println(e.toString);} 
} 
public class Main{ 
    public static void main(String[] args){ 
     new MyClass(new String("string"));//will be invoked comstructor MyClass(Object) 
    } 
} 

當我們創建一個新的實例類的調用首先這類誰調用的構造函數的方法是已知的。 問題:

  1. 這是真的,通過構造函數的返回值的默認類型是void
  2. 是否從類型擦除之後構造函數public <E> MyClass(E e){ System.out.println(e.toString);}相當於public MyClass(Object o){ System.out.println(o.toString);}
+0

構造函數不能返回任何東西。 – Steven

+0

@ St.Antario:你定義的東西不是構造函數。這只是另一種方法。 –

+1

@EnnoShioji。怎麼樣?這是一個通用的構造函數。 –

回答

8

這是真的,默認類型構造的返回值是無效的?

你不給任何顯式返回類型給構造函數。但是,構造函數在內部轉換爲名爲<init>non-static方法,其返回類型爲void

JVM Spec Section 2.9

在Java虛擬機的水平,每constructor用Java編程語言(JLS§8.8)顯示爲具有特殊名稱<init>實例的初始化方法。該名稱由編譯器提供。由於名稱<init>不是有效的標識符,因此它不能直接用於用Java編程語言編寫的程序中。 實例初始化方法只能在Java虛擬機內由invokespecial指令(§invokespecial)調用,並且它們只能在未初始化的類實例上調用。一個實例初始化方法承擔了派生它的構造函數的訪問權限(JLS§6.6)。與返回類型void<clinit>,再次 -

類似地,靜態初始化內部轉換爲一個static方法。

是否從類型擦除下面的構造函數public <E> MyClass(E e){ System.out.println(e.toString);}相當於public MyClass(Object o){ System.out.println(o.toString);}

是的。刪除一個類型參數是它的最左邊界。在這種情況下,由於沒有綁定到E,刪除是Object

假如你宣佈你的構造函數爲:

public <E extends Integer> MyClass(E e){ System.out.println(e.toString);} 

這種擦除是:

public MyClass(Integer e){ System.out.println(e.toString);} 

由於最左邊的束縛的E現在是一個Integer


參考文獻:

+0

@Bohemian請隨時添加我可能錯過的任何東西。謝謝:) –

+1

_但是,一個構造函數在內部轉換爲一個名爲的非靜態方法,其返回類型爲void._此對話正在調用哪裏?在這種情況下,'new MyClass(new String(「string」));'在編譯時,編譯器檢查是否存在構造函數,並且在此編譯器將構造函數轉換爲''後。這是真的嗎? –

+1

@聖安達里奧。當編譯該類時,當時只有編譯器爲構造函數創建了''方法。 –