编译器的行为与通用方法的null参数不同

编译器的行为与通用方法的null参数不同,第1张

编译器的行为与通用方法的null参数不同

该问题是由于JLS规范所致,该规范要求必须将不可推论的类型参数推导为

Object
,即使它不满足界限(并因此会触发编译错误)。

以下是“错误”报告的摘录(为清楚起见,已对其进行了进一步注释):

[“错误” ID 6299211-方法类型变量:推断为空

](http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=6299211)

该程序无法编译:

public class Try {    void m() {        java.util.Collections.max(null);    }}

状态 :已 关闭,不是缺陷。

评估这不是错误
。推理算法无法从参数(

null
)收集任何信息,并且不会在对返回值有任何期望的地方调用该方法。在这种情况下,编译器必须推断出
java.lang.Object
类型变量。


JLS
15.12.2.8推断未解决的类型参数

然后,还可以推断出尚未推断出的所有剩余类型变量

Object


但是,

Object
不是的子类型,
Comparable<? superObject>
因此不在声明的类型变量的范围内
Collections.max

<T extends
Object& Comparable<? super T>
> T max(Collection<?extendsT>)


进一步的探索

使用显式类型参数可以“解决”问题:

HowBizarre.<Number,Integer>doIt(null); // compiles fine in javac

为了表明与

null
参数无关,而与类型推断的绝对缺乏信息更多,可以尝试例如以下两种声明之一:

<T,U extends Comparable<T>> void doIt()<T extends Number,U extends T> void doIt()

在这两种情况下,调用

doIt();
都不会在中进行编译
javac
,因为它必须推断
U
为符合
Object
15.12.2.8,即使这样做会触发编译错误。


关于Eclipse的注意

尽管以上代码片段均未​​在的某些版本中进行编译

javac
,但它们都在Eclipse的某些版本中进行了编译。这可能暗示了Eclipse的错误。众所周知,不同的编译器之间存在分歧。



欢迎分享,转载请注明来源:内存溢出

原文地址:https://54852.com/zaji/5479085.html

(0)
打赏 微信扫一扫微信扫一扫 支付宝扫一扫支付宝扫一扫
上一篇 2022-12-12
下一篇2022-12-12

发表评论

登录后才能评论

评论列表(0条)

    保存