2011-03-22 37 views
0

在java中,我可以使用ClassName.class獲得任何類的類型。但是如果我想獲得一個參數化(通用)集合的類型呢? Collection<MyClass>.class不起作用。如何獲得Java參數化集合類的類型?

這就是我想做的事:

ParameterExpression<Collection<MyClass>> dateParameter = criteriaBuilder.parameter(Collection<MyClass>.class); 

回答

4

由於泛型是如何在Java(類型擦除)來實現,也沒有Collection<MyClass>類。只是標準的Collection類。

泛型實際上是額外的編譯時檢查,它只會以有限的方式將其轉換爲生成的字節碼。特別是,對象不知道它們被實例化了哪些泛型參數,所以你不能調用例如instanceof在運行時檢查此。

大多數反射電話(其中包括使用Class類)忽略了泛型,因爲您不會得到任何類型的安全。即使運行時允許你訪問Collection<MyClass>類,其方法仍然仍然只需要Object,因爲這只是獲取原始類型Collection的語法糖。由於不允許使用這種潛在的誤導性語法,所以Java在這裏可以做出正確的決定,因爲它清楚地表明泛型類在運行時並不存在。

+0

Andrzej:好的,謝謝。你將如何解決上述問題? (問題更新)。只是壓制警告? – 2011-03-22 08:40:29

+0

是的,不幸的是,你可以抑制警告或者使用雙重鑄造(轉換爲原始類型'Class',然後返回到'Class >'),以便無錯誤地進行編譯。不要忘記,並非所有的警告都是不好的 - 只是編譯器會說「我不知道這是否正確」。像這樣的情況,開發人員(但不是編譯器)很清楚這是正確的,這是警告抑制的原因。 – 2011-03-22 08:45:34

0

Acquiring generic class type

public static <C extends Collection, E, T extends Collection<E>> 
Class<T> cast(Class<C> classC, Class<E> classE) 
{ 
    return (Class<T>)classC; 
} 

Class<Collection<MyClass>> clazz = cast(Collection.class, MyClass.class) 
criteriaBuilder.parameter(clazz); 

然而,由於只有原班在運行時通過,該庫將不充分了解詳細的類型,這可能neeed做的工作。

此類庫應該擴展爲接受Type,其中包含更豐富的類型信息。現在的問題變成了如何在編譯時編寫Type<Collection<MyClass>>。 「超級類型令牌」是一種方式。

相關問題