2011-02-13 176 views
7

喜有在Java中沒有辦法讓staticly泛型類類型獲取泛型類類型

我已經結束了,以構建

List<TaskLocalConstraints> l = new ArrayList<TaskLocalConstraints>(); 
    Class<List<TaskLocalConstraints>> c = (Class<List<TaskLocalConstraints>>)l.getClass(); 

我想知道,如果存在這樣的:

Class c = List<TaskLocalConstraints>.class; 

(我真的不想構造新的對象只是爲了得到它的類型)

謝謝

回答

7

由於所有List<something>類實際上對應於在運行相同的類,你可以這樣做:

Class<List<TaskLocalConstraints>> c 
    = (Class<List<TaskLocalConstraints>>) List.class; 

但由於某些原因,Java不喜歡它。與字符串試了一下:

Laj.java:9: inconvertible types 
found : java.lang.Class<java.util.List> 
required: java.lang.Class<java.util.List<java.lang.String>> 
Class<List<String>> c = (Class<List<String>>) List.class; 

好吧,讓我們欺騙它,那麼:

Class<List<String>> c = 
    (Class<List<String>>) (Class<?>) List.class; 

這是愚蠢的,但它的作品。它產生一個「未經檢查」的警告,但你的例子也是如此。請注意,它不會產生與您的示例相同的類。你的例子返回對象的實際類,即ArrayList。這顯然返回List

+0

你的主席剛剛救了我的一天!心靈吹拂! *插入令人興奮的GIF * – 2015-12-22 14:02:23

0

你可以得到List的類,這將是Class c = List.class。不幸的是,在Java中關於泛型的信息不會在運行時保留下來,因此在編譯之後,您的List<TaskLocalConstraints>將變爲簡單的List

+0

我知道...但我問是否有一些workaroud ...在某些情況下,它可能通過反射(例如獲取類型爲當前類的泛型類型)即使在運行時也可以獲得泛型類型... – malejpavouk 2011-02-13 12:23:58

+0

我不認爲這是可能的。你是對的,該語言不允許這樣的結構和`Class.forName`不會理解語法。 – Malcolm 2011-02-13 12:54:15

1

我不確定你是否注意到,但在你的例子中,你將得到java.util.ArrayList類的「c」變量。我不確定這是否是你的觀點。但是,如果我們asume,那是它是:

@SuppressWarnings("unchecked") 
Class<? extends List<TaskLocalConstraints>> c = (Class<? extends List<TaskLocalConstraints>>) ArrayList.class; 

但是如果你需要列表,使用這樣的:

@SuppressWarnings("unchecked") 
Class<? extends List<TaskLocalConstraints>> c = (Class<? extends List<TaskLocalConstraints>>) List.class; 

我添加@SuppressWarnings註釋擺脫警告。此註釋可以用於任何粒度,因此您也可以使用它標記本地代碼。

這種方法的關鍵思想是仿製藥是erasure。在運行時沒有關於它們的信息,以上分配是正確的。

+0

此代碼不起作用,請參閱我的答案。它稍有不同,但會產生相同的「不可轉換的類型」錯誤。 – 2011-02-13 14:19:36

2

基本上,只是矇騙愚弄編譯器。無論如何,它在運行時都是一個簡單的Class

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

Class<List<TaskLocalConstraints>> c = 
     cast(List.class, TaskLocalConstraints.class); 

如果你需要一個真正的Type完整的運行時泛型類型的信息,這是一個不同的故事:

實用方法。

1

我能想到的最接近的解決方法是super type tokens。當然有人在我面前想到它)根據你的情況,你可能會發現這個想法很有用。

乾杯!