2013-11-26 99 views
3

我有以下代碼:Java的泛型類構造函數調用

public class A {} 

public class B extends A {} 

public class C <T extends A> { 

    private final T data; 

    public C(final T data) { 
    this.data = data; 
    } 
} 

public class D<T extends B> extends C<T> { 

    public D(T data) { 
    super(data); 
    } 

    public D() { 
    this(new B()); 
    } 

    public static D<B> create() { 
    return new D(new B()); 
    } 
} 

有班上d編譯錯誤:

error: no suitable constructor found for D(B) 
    this(new B()); 
constructor D.D() is not applicable 
    (actual and formal argument lists differ in length) 
constructor D.D(T) is not applicable 
    (actual argument B cannot be converted to T by method invocation conversion) 
where T is a type-variable: 
T extends B declared in class D 

什麼是困惑我是一個事實,即靜態方法d .create()基本相同,編譯時沒有任何錯誤。任何人都可以解釋此錯誤?和D()和D.create()之間的區別?

+1

您打算用仿製藥混合單字母類名來迷惑大家,其通過約定使用單類型的字母。 – artbristol

回答

1

由於D類的泛型類型T未綁定

這將工作

public class E extends D<B> { 

    public E() { 
     super(new B()); // call to D's constructor public D(T data) 
    } 
} 

通常你會調用D構造這樣:

new D<B>(new B()); 

但你CAN NOT做到這一點

public D() { 
    this<B>(new B()); 
} 

另一個例子。

更改一下代碼,你會看到問題。

class BBB extends B { 
} 

class C<T extends A> { 

    protected final T data; 

    public C(final T data) { 
     this.data = data; 
    } 
} 

class D<T extends B> extends C<T> { 

    public D() { 
     this(new B()); 
    } 

    public T getData(){ 
     return data; 
    } 
} 

D<BBB> dOfBBB = new D<BBB>(); 
BBB data = dOfBBB.getData(); // So if this(new B()) would work 
           // how can the data then be returned? 
           // Because BBB is returned but it would be 
           // initialized with only a B instance 
+0

謝謝你的解釋。這是否意味着如果我想保留D類泛型(爲了能夠以與C - > D相同的方式擴展它),我只能使用D.create() - 我的意思是沒有辦法重寫D ()錯誤免費? – Petr

+0

@Petr是的,在你的情況下,我會遵循波希米亞的答案。 –

4

誤差是存在的,因爲D類目前還不知道該類型將是B,只有泛型類型將延長B - 你以爲這將是B因爲沒有其他類(還)在你的類層次結構中(編譯器必須考慮的事實可能會在未來發生變化)。


注意的是,在工廠方法你實例化原料類型D(一個沒有泛型參數)。相反,提供類型:

你應該改變:

public static D<B> create() { 
    return new D(new B()); 
} 

到:

public static D<B> create() { 
    return new D<B>(new B()); // Note: Added generic parameter <B> 
} 
相關問題