我可以在Java中的generics类型上调用.class吗?

我想知道Java中是否有办法做类似的事情

Class c = List.class; Class c2 = List.class; 

我需要这样的东西来创建一个存储类名(带有generics类型)的地图和我以后可以查找的相应对象。 例如,

 Map dataMap = new HashMap(); dataMap.put(c, listOfStrings); dataMap.put(c2, listOfDates); 

由于运行期间的类型擦除,这是不可能的吗?

你不能这样,但你可以使用Guice与TypeLiteral相同的方法实现你的整体目标。 如果您已经使用Guice,我建议您直接使用它 – 否则,您可能想要创建自己的类似类。

本质上,我们的想法是指定类型参数的generics类的子类直接保留该信息。 所以你写了类似的东西:

 TypeLiteral literal = new TypeLiteral>() {}; 

然后你可以使用literal.getClass().getGenericSuperclass()并从中获取类型参数。 TypeLiteral本身不需要任何有趣的代码(我不知道它是否在Guice 有任何其他原因)。

不,这是不可能的。 您甚至无法在代码中引用List.class – 这会导致编译错误。 List只有一个单独的类对象,它被称为List.class

由于运行期间的类型擦除,这是不可能的吗?

正确。

顺便说一下,这是一种通用类型,而不是带注释的类型。

更新

再想一想,通过调整Josh Bloch的类型安全异构容器 (发表于Effective Java 2nd Ed。,Item 29),你可以得到一些与你上面的Map非常接近的东西:

 public class Lists { private Map, List> lists = new HashMap, List>(); public  void putList(Class type, List list) { if (type == null) throw new NullPointerException("Type is null"); lists.put(type, list); } public  List getList(Class type) { return (List)lists.get(type); } } 

取消选中getList中的强制转换,发出警告,但恐怕我们无法避免。 但是,我们知道为X类存储的值必须是List ,因为这是由编译器保证的。 所以我认为putList是安全的(如果按照规则进行操作,即 – 从不使用普通的非putList Class参数调用putList ),因此可以使用@SuppressWarnings("unchecked")来抑制它。

你可以像这样使用它:

 Lists lists = new Lists(); List integerList = new ArrayList(); List stringList = new ArrayList(); ... lists.putList(Integer.class, integerList); lists.putList(String.class, stringList); List storedList = lists.getList(Integer.class); assertTrue(storedList == integerList); 

这是不可能的,因为你正在尝试。
但是你可以装饰这些列表并创建一个MyListDatesMyListString ,并将它们存储在hashmap中