Kas*_*erg 17 java generics reflection casting
我使用.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
Run Code Online (Sandbox Code Playgroud)
下一行有效:
Class<List<Integer>> tListInt3 =
(Class<List<Integer>>) ((Class<Integer>)List.class);
Run Code Online (Sandbox Code Playgroud)
为什么声明tListInt2和tListGeneric给出和错误?为什么upcast然后downcast而tListInt3不会产生错误?有更好的方式申报tListInt3吗?
亲切的问候,
Kasper van den Berg
PS.如果您希望将代码视为需要此类型信息的外部通用容器,请告诉我们.如果需要,我会发布它.
irr*_*ble 27
Class<List<Integer>> tListInt3 =
(Class<List<Integer>>) ((Class<Integer>)List.class);
Run Code Online (Sandbox Code Playgroud)
这不起作用.你可能意味着
Class<List<Integer>> tListInt3 =
(Class<List<Integer>>) ((Class)List.class);
Run Code Online (Sandbox Code Playgroud)
我们总是可以通过向上投射然后向下投射从一种类型转换为另一种类型
Integer x = (Integer)(Object)"string";
Run Code Online (Sandbox Code Playgroud)
类型List.class是Class<List>; 它不是子类型/超类型,Class<List<Whatever>>因此两种类型之间的直接转换是非法的.
可以说,Class<List<Integer>>不存在 - 只有一个类List; 没有这样的类List<Integer>(实际上只是List在运行时)
但是,这是Java类型系统的缺陷; 在实践中我们确实需要这样的东西Class<List<Integer>>.我们的解决方案 - 铸造和假装Class<List<Int>>退出 - 同样存在缺陷 - 但这不是我们的错.