[英]How to properly specify a Class<?> parameter using Generics
我的目標是實現一個接受類實例的操作,但前提是具體傳遞的類繼承自Collection。
我在無法解決的代碼上收到編譯器警告。
package com.fun.with.generics;
import java.util.ArrayList;
import java.util.Collection;
public class AcceptTypedClass
{
// Warning here on 'Collection': ... raw type, references should be parameterized.
private static void printCollectionClass( Class<? extends Collection> c )
{
System.out.println( c.getName() );
}
public static void main( String[] args )
{
// Warning here on ArrayList: ... raw type, references should be parameterized.
Class<ArrayList> arrayList = ArrayList.class;
printCollectionClass( arrayList );
}
}
我確實理解警告消息,但是如果我通過添加缺少的類型參數(如下所示)來修復警告,則會出現錯誤。
Class<ArrayList<?>> arrayList = ArrayList.class;
有人可以解釋一下嗎? 問題是我是否可以編寫上面的代碼,以便沒有任何警告(並且該代碼有效)?
從根本上來說,類是作為通用“類型標記”的錯誤選擇,即在運行時指示某種特定類型的某些方法,因為在運行時沒有可用的通用類型信息。
最好使用以下任一方法:
實際的“類型令牌”類,例如GSON的TypeToken
或Guice的TypeLiteral
。
請注意,這兩個類的Javadoc以以下內容開頭:
表示通用類型T。Java尚未提供表示通用類型的方法,因此此類可以。 ...
通過創建TypeToken
的匿名子類來創建GSON類型令牌:
TypeToken<ArrayList<String>> typeToken = new TypeToken<ArrayList<String>>() {};
子類化操作通過typeToken.getClass().getGenericSuperclass()
將泛型類型信息烘焙到typeToken
實例中。
請注意,但是您不能通用地執行此操作-您必須使用實際類作為通用參數而不是類型變量來創建子類。
您可以將printCollectionClass
方法更改為
private static <T extends Collection<?>> void printCollectionClass(Class<T> c) {
System.out.println(c.getName());
}
public static void main(String[] args) {
printCollectionClass(ArrayList.class);
}
在這里, printCollectionClass
將接受從collection繼承的類。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.