我们都知道有关Java集合的泛型,需要E
或通配符?
来实例化特定集合中允许的内容/对象。
我的问题是,我们可以从下面的代码中了解特定集合的通配符或对象吗?
Object inbound = java.io.ObjectInputStream().readObject();
if(inbound instanceof List<?>) {
// know `?.getClass()`
}
答案 0 :(得分:6)
没有。由于类型擦除,在运行时期间无法区分List
s。
答案 1 :(得分:2)
如果inbound
是在类型声明中定义其类型参数的类,则只能找到类型参数。例如,假设您序列化了NodeList
的实例,其声明如下:
final class NodeList extends ArrayList<Node> { }
然后当你反序列化它时,你可以这样做:
Object inbound = ois.readObject();
if (inbound instanceof List<?>) {
Type t = inbound.getClass().getGenericSuperclass();
if (t instanceof ParameterizedType) {
ParameterizedType pt = (ParameterizedType) t;
for (Type p : pt.getActualTypeArguments()) {
if (p instanceof TypeVariable<?>)
System.out.println("Unknown");
else
System.out.println(p); /* Prints "interface Node" */
}
}
}
答案 2 :(得分:0)
如果您确定该列表至少包含一个元素,那么您可以在这种情况下简单地调用getClass
。
否则,这实际上是不可能的,尽管您可以将List与List一起序列化。
答案 3 :(得分:0)
恕我直言,如果您需要这样做,最佳解决方案是使用Guice:http://blog.publicobject.com/2008/11/guice-punches-erasure-in-face.html。
正如其他人所提到的,类型擦除是问题的根源。一个很好的解释是http://docs.oracle.com/javase/tutorial/java/generics/erasure.html。
您可以查看the source for ArrayList
并查看其工作原理示例。 ArrayList
持有Object[]
(第111行)。它不知道对象的类型。你可以看到'类型安全'实际上只是通过演员阵容实现的,例如:第371行。