1

众所周知,Java 集合的泛型E或通配符?是实例化特定集合中允许的内容/对象所必需的。

我的问题是我们可以从下面的代码中知道特定集合的通配符或对象吗?

Object inbound = java.io.ObjectInputStream().readObject();
if(inbound instanceof List<?>) {
   // know `?.getClass()`
}
4

4 回答 4

6

不。由于类型擦除,在运行时没有办法区分Lists。

于 2012-08-27T17:02:31.063 回答
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" */
    }
  }
}
于 2012-08-27T17:38:29.530 回答
0

如果您确定列表至少包含一个元素,则可以,在这种情况下,您可以简单地调用getClass它。

否则,这实际上是不可能的,尽管您可以将正确的 Class 对象与 List 一起序列化。

于 2012-08-27T17:24:21.827 回答
0

恕我直言,如果您需要这样做,最好的解决方案是使用 Guice:http ://blog.publicobject.com/2008/11/guice-punches-erasure-in-face.html 。

正如其他人所提到的,类型擦除是问题的根源。一个很好的解释是http://docs.oracle.com/javase/tutorial/java/generics/erasure.html

您可以查看源代码ArrayList并查看其工作原理的示例。ArrayList持有一个(第Object[]111 行)。它不知道对象的类型。您可以看到“类型安全”实际上只是通过强制转换实现的,例如第 371 行。

于 2012-08-27T17:47:55.300 回答