我使用.class
-operator向泛型类提供有关所包含类型的信息。对于非泛型的包含类型,例如Integer.class
,这没有任何问题。但由于包含的类型是泛型,例如List<Integer>.class
或List.class
,它会导致有关类类型转换的编译时错误。
有一种方法可以绕过这些错误,但我很好奇这里发生了什么。有人能解释一下发生了什么吗?为什么事情是这样的?以及规避这个问题的最好方法是什么?
下面几行代码演示了这个问题:注意,外部泛型类型需要Class<T>
作为参数,所以在本例中是Class<List<Integer>>
。
Class<Integer> tInt = Integer.class; // Works as expected.
Class<List> tList = List.class; // Works with warning, but is not
// what i'm looking for.
Class<List<Integer>> tListInt1 = List.class; // Error
Class<List<Integer>> tListInt2 = (Class<List<Integer>>) List.class; // Error
Class<List<?>> tListGeneric = (Class<List<Integer>>) List.class; // Error
下面的代码行可以工作:
Class<List<Integer>> tListInt3 =
(Class<List<Integer>>) ((Class<Integer>)List.class);
为什么tListInt2
和tListGeneric
的声明会给出和错误?为什么tListInt3
的向上转换和向下转换不会产生错误?有没有更好的方法来声明tListInt3
向您致以亲切的问候,
Kasper van den Berg
ps。如果您希望看到需要此类型信息的外部泛型容器的代码,请告诉我;如果需要,我会发布它。
发布于 2011-09-22 03:56:58
Class<List<Integer>> tListInt3 =
(Class<List<Integer>>) ((Class<Integer>)List.class);
这不管用。你的意思可能是
Class<List<Integer>> tListInt3 =
(Class<List<Integer>>) ((Class)List.class);
我们总是可以通过向上转换然后向下转换从一种类型转换为另一种类型。
Integer x = (Integer)(Object)"string";
List.class
的类型是Class<List>
;它不是Class<List<Whatever>>
的子类型/父类型,因此两种类型之间的直接转换是非法的。
可以说Class<List<Integer>>
并不存在--只有一个用于List
的类;没有用于List<Integer>
的类(在运行时它实际上就是List
)
然而,这是Java类型系统的一个缺陷;在实践中,我们确实需要像Class<List<Integer>>
这样的东西。我们的解决方案--强制转换和假装Class<List<Int>>
退出--同样有缺陷--但这不是我们的错。
https://stackoverflow.com/questions/7502243
复制相似问题