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

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-30 20:15:51  来源:igfitidea点击:

Java casting ".class"-operator used on a generic type, e.g. List, to "Class<List<?>>" and to "Class<List<Integer>>"

javagenericsreflectioncasting

提问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>.classor List.classit 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 tListInt2and tListGenericgive and error? Why does upcast and then downcast with tListInt3not produce an error? Is there a better way to declare tListInt3?

为什么声明tListInt2tListGeneric给出和错误?为什么向上转换然后向下转换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.classis Class<List>; it is not a subtype/supertype of Class<List<Whatever>>therefore direct cast between the two types is illegal.

的类型List.classClass<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 Listat 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>>退出——同样有缺陷——但这不是我们的错。