Jea*_*let 8 java generics reflection language-design bounded-wildcard
假设我在Java中有这个:
List<String> list = new ArrayList<String>();
list.getClass();
Run Code Online (Sandbox Code Playgroud)
最后一个表达式的类型是Class<? extends List>.我理解为什么,由于擦除,它不可能Class<? extends List<String>>.但为什么不能呢Class<? extends List<?>>?
如果我想将这个表达式的结果分配给一个变量,以某种方式保存这个类实际上是某种类型的信息,我是否无法避免未经检查的强制转换警告和原始类型警告List?
Class<? extends List> listClass = list.getClass(); // raw type warning
Class<? extends List<?>> listClass = (Class<? extends List<?>>) list.getClass(); // unchecked cast warning
Run Code Online (Sandbox Code Playgroud)
当首次引入泛型,getClass返回时Class<? extends X>,X调用它的表达式的静态类型在哪里.这种行为导致了不合理的编译问题,正如此Oracle错误中所报告的那样.这是bug报告的例子:
以下程序片段无法编译
Run Code Online (Sandbox Code Playgroud)void f(List<Integer> li, List<String> ls) { if (li.getClass() == ls.getClass()) ; }由于交叉点
Class<List<Integer>>和Class<List<String>>是空的.
通过扩大现在的返回类型getClass来解决此问题.从文档:
实际结果的类型是
Class<? extends |X|>其中|X|是静态类型上其表达的擦除getClass被调用.
这解决了上述问题,但因此导致了您的问题指出的问题.不久之后,报告了另一个错误,争论如下:
我认为
getClass()输入规则可以更改为Class<? extends wildcard(T)>通配符操作定义如下:if
Tis parametrized,wildcard(T)=erasure(T)<?>else,wildcard(T)=T理由:
此规则引入原始类型.原始类型必须仅用于与遗留代码交互.
新规则引入了通配符.参数化类型和通配符之间的关系基于子类型规则.参数化类型和通配符之间的关系基于原始类型转换.
这个错误没有采取行动,至今仍未解决,并提出以下抗议:
该提议意味着
getClass()将返回一个Class<? extends ArrayList<?>>与其他Class<? extends ArrayList<?>>对象不兼容的对象.这与现有代码兼容,如:Run Code Online (Sandbox Code Playgroud)List<String> l = ...; Class<? extends List> c = l.getClass();因为RHS的新类型
Class<? extends List<?>>是子类型Class<? extends List>.丰富Class类型参数的一个缺点是它会破坏惯用法
Class.cast.今天你可以写:Run Code Online (Sandbox Code Playgroud)List<Integer> x = ...; Class<? extends List> cl = x.getClass(); List<Integer> y = cl.cast(null);并获得警告
cast(),因为未经检查的转换List为List<Integer>.但是根据提案,类似的代码不能编译:Run Code Online (Sandbox Code Playgroud)List<Integer> x = ...; Class<? extends List<?>> cl = x.getClass(); List<Integer> y = cl.cast(null);因为
List<?>返回者cast()无法转换为List<Integer>.避免错误的唯一方法是投cl.cast(..)达List和遭受选中转换警告List<Integer>.这实际上getClass()已经是这样了.总体而言,该提案似乎是一个好主意,但它具有中等复杂性和相当小的收益.
(删节并纠正了一些拼写错误)