我可以在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
– 这会导致编译错误。 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);
这是不可能的,因为你正在尝试。
但是你可以装饰这些列表并创建一个MyListDates
和MyListString
,并将它们存储在hashmap中