我想知道Java中是否有办法做类似的事情
Class c = List<String>.class;
Class c2 = List<Date>.class;
Run Code Online (Sandbox Code Playgroud)
我需要这样的东西来创建一个存储类名(带有泛型类型)的地图和我以后可以查找的相应对象.例如,
Map<Class, Object> dataMap = new HashMap<Class, Object>();
dataMap.put(c, listOfStrings);
dataMap.put(c2, listOfDates);
Run Code Online (Sandbox Code Playgroud)
这是不可能的,因为运行期间的类型擦除?
Jon*_*eet 12
你不能这样,但你可以使用与Guice相同的方法实现你的整体目标TypeLiteral.如果您已经使用Guice,我建议您直接使用它 - 否则,您可能想要创建自己的类似类.
本质上,这个想法是指定类型参数的泛型类的子类直接保留该信息.所以你写了类似的东西:
TypeLiteral literal = new TypeLiteral<List<String>>() {};
Run Code Online (Sandbox Code Playgroud)
然后你可以使用literal.getClass().getGenericSuperclass()并从中获取类型参数.TypeLiteral本身不需要任何有趣的代码(我不知道它是否在Guice 中有任何其他原因).
不,这是不可能的.您甚至无法List<String>.class在代码中引用它 - 它会导致编译错误.只有一个单个类对象List,它被调用List.class.
这是不可能的,因为运行期间的类型擦除?
正确.
顺便说一下,这是一种通用类型,而不是带注释的类型.
再想一想,通过调整Josh Bloch的类型安全异构容器(发布于Effective Java 2nd Ed.,Item 29),你可以得到一些与你上面的Map非常接近的东西:
public class Lists {
private Map<Class<?>, List<?>> lists =
new HashMap<Class<?>, List<?>>();
public <T> void putList(Class<T> type, List<T> list) {
if (type == null)
throw new NullPointerException("Type is null");
lists.put(type, list);
}
public <T> List<T> getList(Class<T> type) {
return (List<T>)lists.get(type);
}
}
Run Code Online (Sandbox Code Playgroud)
演员getList阵容未经检查,发出警告,但恐怕我们无法避免.但是,我们知道为class存储的值X必须是a List<X>,因为这是由编译器保证的.所以我认为演员阵容是安全的(如果你遵守规则,即 - 从不putList使用普通的非泛型Class参数调用),因此可以使用它来抑制@SuppressWarnings("unchecked").
你可以像这样使用它:
Lists lists = new Lists();
List<Integer> integerList = new ArrayList<Integer>();
List<String> stringList = new ArrayList<String>();
...
lists.putList(Integer.class, integerList);
lists.putList(String.class, stringList);
List<Integer> storedList = lists.getList(Integer.class);
assertTrue(storedList == integerList);
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
9210 次 |
| 最近记录: |