2017-08-03 102 views
2

假設我有以下類:在構造函數中指定重複的泛型類型?

import java.util.function.Function 
import java.util.List 

class Foo<X, Y> { 
    public Function<X, Y> converter; 
    public List<X> inputs; 

    public Foo(Function<X, Y> converter, List<X> inputs) { 
     this.converter = converter; 
     this.inputs = inputs; 
    } 
} 

我想添加一個構造函數的輸入的List<X>,並自動提供一個身份功能與它一起去:

public Foo(List<X> inputs) { 
    this(Function.identity(), inputs); 
} 

然而,這給我一個錯誤:The constructor Foo<X, Y>(Function<Object,Object>, List<X>) is undefined。 在另一方面,下面的編譯:

public static <X> Foo<X, X> makeFoo(List<X> inputs) { 
    return new Foo<>(Function.identity(), inputs); 
} 

事實上,以下也適用:

public Foo(List<X> inputs) { 
    this.converter = (Function<X, Y>)Function.identity(); 
    this.inputs = inputs; 
} 

但是在這裏,我不得不從Function<Object, Object> to Function<X, Y>讓一個未經檢查的演員。它會工作,但我知道通常有一種方法可以處理泛型(或者Java中的任何東西),而不需要強制轉換。

有沒有辦法使這個構造函數與這個工作而不是訴諸靜態方法或鑄造?

我曾嘗試調用this((Function<X, X>)Function.identity(), inputs)的其他構造函數,將構造函數重寫爲public Foo<X, X>(List<X> inputs),並調用其他構造函數<X, X>this(Function.identity(), inputs),但沒有任何效果。

好像應該有讓編譯器的方式知道Function.identity()參數,或創建的Foo,爲<X, X>型的,但我不能想出什麼好的地方把它。我環顧四周,找不到以任何方式投射或指定類型的方法。我可以找到與該主題最接近的一個類型目擊者,從hereBoxDemo.<Integer>addBox(Integer.valueOf(10), listOfIntegerBoxes);」,但這似乎是一個不同的場景。還有一個有趣的「01​​」建議從this SO回答,但這似乎也不適用。我認爲不適用的原因是因爲我的構造函數沒有任何類型參數,如public <Z> Foo(...)

感謝您的幫助。

回答

3

不,沒有更好的辦法。您不能限制此構造函數僅在XY是相同類型時才起作用,因此構造函數必須假定它們不同,並且Function.identity()相應地不一定是正確的類型。

也就是說,使用靜態工廠方法通常比暴露構造函數更好,如果你這樣做,你會沒事的。

相關問題