Java:List<;E>;了解E.getClass()

Java:List<;E>;了解E.getClass(),java,collections,wildcard,Java,Collections,Wildcard,正如我们所知,Java集合的泛型需要E或通配符?来实例化特定集合中允许的内容/对象 我的问题是,有没有一种方法可以从下面的代码中知道特定集合的通配符或对象 Object inbound = java.io.ObjectInputStream().readObject(); if(inbound instanceof List<?>) { // know `?.getClass()` } objectinbound=java.io.ObjectInputStream().rea

正如我们所知,Java集合的泛型需要
E
或通配符
来实例化特定集合中允许的内容/对象

我的问题是,有没有一种方法可以从下面的代码中知道特定集合的通配符或对象

Object inbound = java.io.ObjectInputStream().readObject();
if(inbound instanceof List<?>) {
   // know `?.getClass()`
}
objectinbound=java.io.ObjectInputStream().readObject();
if(入站实例列表){
//知道“?.getClass()`
}

否。由于类型擦除,在运行时无法区分
列表
s。

否。由于类型擦除,在运行时无法区分
列表
s。

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


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

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


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

只有当
inbound
是在类型声明中定义其类型参数的类时,才能找到类型参数。例如,假设您序列化了如下声明的
NodeList
实例:

final class NodeList extends ArrayList<Node> { }
final类节点列表扩展了ArrayList{}
然后反序列化时,可以执行以下操作:

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" */
    }
  }
}
objectinbound=ois.readObject();
if(入站实例列表){
类型t=inbound.getClass().getGenericSuperclass();
if(参数化类型的t实例){
参数化类型pt=(参数化类型)t;
for(类型p:pt.getActualTypeArguments()){
if(p instanceof TypeVariable)
System.out.println(“未知”);
其他的
System.out.println(p);/*打印“接口节点”*/
}
}
}

只有当
inbound
是在类型声明中定义其类型参数的类时,才能找到类型参数。例如,假设您序列化了如下声明的
NodeList
实例:

final class NodeList extends ArrayList<Node> { }
final类节点列表扩展了ArrayList{}
然后反序列化时,可以执行以下操作:

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" */
    }
  }
}
objectinbound=ois.readObject();
if(入站实例列表){
类型t=inbound.getClass().getGenericSuperclass();
if(参数化类型的t实例){
参数化类型pt=(参数化类型)t;
for(类型p:pt.getActualTypeArguments()){
if(p instanceof TypeVariable)
System.out.println(“未知”);
其他的
System.out.println(p);/*打印“接口节点”*/
}
}
}

IMHO,如果需要这样做,最好的解决方案是使用Guice:

正如其他人提到的,类型擦除是问题的根源。一个好的解释就在眼前


您可以查看并查看一个示例来说明这是如何工作的。
ArrayList
包含一个
对象[]
(第111行)。它不知道对象的类型。您可以看到,“类型安全性”实际上只是通过强制转换实现的,例如第371行。

IMHO,如果需要这样做,最好的解决方案是使用Guice:

正如其他人提到的,类型擦除是问题的根源。一个好的解释就在眼前


您可以查看并查看一个示例来说明这是如何工作的。
ArrayList
包含一个
对象[]
(第111行)。它不知道对象的类型。您可以看到“类型安全性”实际上是通过强制转换实现的,例如第371行。

有没有一种方法可以在不进入
列表的元素的情况下获取
e
?到目前为止,这是我能接受的最接近的答案。有没有一种方法可以在不进入
列表
元素的情况下获得
E
?到目前为止,这是我接受的最接近的答案。但是如果
List.size()==0
,这个解决方案将无效。我不明白为什么
TypeLiteral
路由即使列表大小为0也不起作用。我链接到的博客文章中的示例在没有任何元素的情况下应该可以正常工作。您的问题是希望“
//know?.getClass()
”。您可以调用
TypeLiteral.getRawType()
来获取
。但是如果
List.size()==0
,此解决方案将无效。我不明白为什么
TypeLiteral
路由即使列表大小为0也无法工作。我链接到的博客文章中的示例在没有任何元素的情况下应该可以正常工作。您的问题是希望“
//know?.getClass()
”。您可以调用
TypeLiteral.getRawType()
来获取
。泛型都是在编译时完成的。它基本上是额外的编译器检查和语法糖。所有泛型类型信息在运行时都不可用。泛型都是在编译时完成的。它基本上是额外的编译器检查和语法糖。所有泛型类型信息在运行时都不可用。