Java:List <e>知道E.getClass()</e>

时间:2012-08-27 17:00:19

标签: java collections wildcard

我们都知道有关Java集合的泛型,需要E或通配符?来实例化特定集合中允许的内容/对象。

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

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

4 个答案:

答案 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行。