Java 将用于泛型类型(例如 List)的“.class”运算符转换为“Class<List<?>>”和“Class<List<Integer>>”
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/7502243/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Java casting ".class"-operator used on a generic type, e.g. List, to "Class<List<?>>" and to "Class<List<Integer>>"
提问by Kasper van den Berg
I use the .class
-operator to supply information about the contained type to a generic class. For non-generic contained types, e.g. Integer.class
, this works without any problems. But with the contained type being a generic, e.g. List<Integer>.class
or List.class
it results in compile time errors about class casting.
我使用.class
-operator 向泛型类提供有关所包含类型的信息。对于非泛型包含的类型,例如Integer.class
,这没有任何问题。但是包含的类型是泛型的,例如,List<Integer>.class
或者List.class
它会导致关于类转换的编译时错误。
There is a way to circumvent the errors, but I'm curious about what is happening here. Can someone explain what is happening?, why things are as they are?, and what the best way to circumvent the problem is?
有一种方法可以规避错误,但我很好奇这里发生了什么。有人能解释一下发生了什么吗?为什么事情是这样?以及规避问题的最佳方法是什么?
The following lines demonstrate the problem:
Note the outer generic type expects Class<T>
as parameter, so in this case Class<List<Integer>>
.
下面几行代码演示了这个问题:注意外部泛型类型需要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
The next line works:
下一行有效:
Class<List<Integer>> tListInt3 =
(Class<List<Integer>>) ((Class<Integer>)List.class);
Why do the declarations of tListInt2
and tListGeneric
give and error?
Why does upcast and then downcast with tListInt3
not produce an error?
Is there a better way to declare tListInt3
?
为什么声明tListInt2
和tListGeneric
给出和错误?为什么向上转换然后向下转换tListInt3
不会产生错误?有没有更好的声明方式tListInt3
?
With kind regards,
Kasper van den Berg
亲切的问候,
Kasper van den Berg
ps. Let me know if you like to see code the outer generic container that needs this type information; i'll post it if needed.
附:如果您想查看需要此类型信息的外部通用容器的代码,请告诉我;如果需要,我会发布它。
回答by irreputable
Class<List<Integer>> tListInt3 =
(Class<List<Integer>>) ((Class<Integer>)List.class);
that doesn't work. you probably meant
那行不通。你可能的意思是
Class<List<Integer>> tListInt3 =
(Class<List<Integer>>) ((Class)List.class);
we can always cast from one type to another by up-cast then down-cast
我们总是可以通过向上转换然后向下转换从一种类型转换为另一种类型
Integer x = (Integer)(Object)"string";
The type of List.class
is Class<List>
; it is not a subtype/supertype of Class<List<Whatever>>
therefore direct cast between the two types is illegal.
的类型List.class
是Class<List>
; 它不是 的子类型/超类型,Class<List<Whatever>>
因此在两种类型之间直接转换是非法的。
It can be argued that Class<List<Integer>>
doesn't exist - there is only a class for List
; there is no such class for List<Integer>
(which really is just List
at runtime)
可以Class<List<Integer>>
说不存在 - 只有一个类用于List
; 没有这样的类List<Integer>
(实际上只是List
在运行时)
However, this is a flaw of Java type system; in practice we do need things like Class<List<Integer>>
. Our solution - casting and pretending Class<List<Int>>
exits - is likewise flawed - but it's not our fault.
然而,这是Java类型系统的一个缺陷;在实践中,我们确实需要像Class<List<Integer>>
. 我们的解决方案——铸造和假装Class<List<Int>>
退出——同样有缺陷——但这不是我们的错。