2011-02-13 172 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。当然有人在我面前想到它)根据你的情况,你可能会发现这个想法很有用。

干杯!