2012-12-16 53 views
3

我堅持一個愚蠢的問題,我不明白。構造與一般類是不確定的

class Foo<T extends Collection<E>, E> { 
    private Class<T> collectionClass; 
    private Class<E> elementClass; 

    public Foo(Class<T> collectionClass, Class<E> elementClass) { 
     this.collectionClass = collectionClass; 
     this.elementClass = elementClass; 
    } 
} 

當我嘗試運行此

Foo<Collection<String>, String> foo = 
    new Foo<Collection<String>, String>(
     Collection.class, 
     String.class); 

我得到一個編譯錯誤

java.lang.Error: Unresolved compilation problem: 
The constructor Foo<Collection<String>,String>(Class<Collection>, Class<String>) is undefined 

爲什麼?如果我抹去仿製藥,這是確定

Foo foo = 
    new Foo(
     Collection.class, 
     String.class); 

如果有人有一個想法,這將是巨大的,並阻止我一聲我的頭在牆上。

回答

4

有沒有這樣的事,作爲一個Collection<String>.class,就是問題所在。您的選擇包括

  • 不使用反射;你爲什麼要用反射?
  • 接受不安全投
  • 一個使用的各種工具,需要參照泛型類型在運行時,如番石榴的TypeToken
+0

最後我重構我的API,以避免這種需要。謝謝。 – MarcDeXeT

0

沒有運氣,因爲類型擦除,見this question

然而一個原始收藏品類和元素類可以被用來生成一種類型安全Collection<String>對象。因此,刪除Collection中的E的冗餘,作爲集合。

0

您的使用情況下,你也許可以放鬆構造方法的參數類型

public Foo(Class<?> collectionClass, Class<E> elementClass) 
{ 
    this.collectionClass = (Class<T>)collectionClass; 
    this.elementClass = elementClass; 
} 

Foo<Collection<String>, String> foo = new Foo<>(Collection.class, String.class); 

有較少的類型檢查,因此用戶必須確保一個錯誤的類不通過的,像

Foo<Set<String>, String> foo = new Foo<>(List.class, String.class); 
    ^^^         ^^^^ 
+0

這會給你不健康的代碼。 –

+0

希望包含取消勾選的危險,因爲錯誤的代碼太明顯了。 – irreputable

+0

錯誤代碼對於合理程度的概率顯而易見的上下文很小。 –

0

好的,

我已經看過其他人的答案,並不是最好的...

在奧賴利虎書(5版)(P167),他們提出了一個非常明確的聲明:構造CAN NOT有它的簽名通配符...

1

有沒有什麼你可以做些什麼。只是施展它

new Foo<Collection<String>, String>(
    (Class<Collection<String>>)(Class<?>)Collection.class, 
    String.class);