java – 当使用非泛型方法覆盖泛型方法时,为什么subsignature和unchecked规则在返回类型上以这种方式工作?

前端之家收集整理的这篇文章主要介绍了java – 当使用非泛型方法覆盖泛型方法时,为什么subsignature和unchecked规则在返回类型上以这种方式工作?前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。

public class Base {

     

为什么在Derived类中定义重写方法f1()和f3()不会产生编译错误,比如Derived类中的重写f2()方法的定义(它给出编译错误“返回类型与Base.f2()不兼容”)?

JLS中的子签名覆盖规则允许覆盖方法(在Derived类中)是非泛型的,而重写方法(在Base类中)是通用的.

未经检查的覆盖规则允许在子类List< String>中创建返回类型.代替List< T>在基类.

但我无法解释下面的行为差异,我不明白为什么fin()和f3()覆盖Derived类中的定义成功编译(在Eclipse,SE8上),忽略了f3()的有界类型参数所施加的限制f1()的有界通配符!

附:我的猜测 – 在Derived编译器中的f1()和f3()中将两个方法视为仅返回“原始”List – 编译器首先进行擦除(此时仅在Derived!中),然后将Derived中的这些擦除方法与未擦除的方法进行比较(到目前为止)Base中的方法.现在未经检查的覆盖规则是正常的(并且不需要检查边界 – 这根本不可能),编译器决定这是正确的覆盖和编译更进一步……在Base.f1()和Base的编译泛型结束时的某处.f3()也擦掉:)))

This SO answer还为这个主题添加了想法.

最佳答案
尽管原始声明是通用的,但您的f1和f3覆盖不是通用的.编译允许覆盖的返回类型与原始返回类型不同,因为它们具有相同类型的擦除(List).我认为这是从JLS 8.4.5开始的,虽然坦率地说我发现规范的这一部分有点令人困惑.

如果您将覆盖更改为通用:

…然后都无法编译:

error: 

请注意,即使在原始代码中,javac也会针对不安全的转换发出警告,如果使用-Xlint:unchecked,则会提供详细信息:

return type requires unchecked conversion from List

猜你在找的Java相关文章