Java将“.class”-operator用于generics类型,例如List,“Class <List >”和“Class <List >”

我使用.class -operator将有关包含类型的信息提供给generics类。 对于非generics包含的类型,例如Integer.class ,这没有任何问题。 但是由于包含的类型是通用的,例如List.classList.class它会导致关于类转换的编译时错误。

有办法规避错误,但我很好奇这里发生了什么。 有人可以解释发生了什么吗?为什么事情就像它们一样?以及解决问题的最佳方法是什么?

以下行演示了此问题:请注意,外部generics类型需要Class作为参数,因此在本例中为Class<List>

 Class tInt = Integer.class; // Works as expected. Class tList = List.class; // Works with warning, but is not // what i'm looking for. Class<List> tListInt1 = List.class; // Error Class<List> tListInt2 = (Class<List>) List.class; // Error Class<List> tListGeneric = (Class<List>) List.class; // Error 

下一行有效:

 Class<List> tListInt3 = (Class<List>) ((Class)List.class); 

为什么tListInt2tListGeneric的声明给出错误? 为什么使用tListInt3然后向下转换不会产生错误? 是否有更好的方法来声明tListInt3

亲切的问候,
Kasper van den Berg

PS。 如果您希望将代码视为需要此类型信息的外部通用容器,请告诉我们。 如果需要,我会发布它。

 Class> tListInt3 = (Class>) ((Class)List.class); 

这不起作用。 你可能意味着

 Class> tListInt3 = (Class>) ((Class)List.class); 

我们总是可以通过向上投射然后向下投射从一种类型转换为另一种类型

  Integer x = (Integer)(Object)"string"; 

List.class的类型是Class ; 它不是Class>的子类型/超类型,因此两种类型之间的直接转换是非法的。

可以说Class>不存在 – List只有一个类; List没有这样的类(在运行时它实际上只是List

但是,这是Java类型系统的缺陷; 在实践中,我们确实需要Class>东西。 我们的解决方案 – 铸造和假装Class>退出 – 同样存在缺陷 – 但这不是我们的错。