
该问题是由于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 extendsObject& 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为符合
Object15.12.2.8,即使这样做会触发编译错误。
关于Eclipse的注意
尽管以上代码片段均未在的某些版本中进行编译
javac,但它们都在Eclipse的某些版本中进行了编译。这可能暗示了Eclipse的错误。众所周知,不同的编译器之间存在分歧。
欢迎分享,转载请注明来源:内存溢出
微信扫一扫
支付宝扫一扫
评论列表(0条)