Java NullPointerException从何而来?
我试图编写一个方法,将一个两位数的数字转换为2000+的数字,返回所有其他数字的原样,并在将null作为参数传递时返回null 此实现按预期工作Java NullPointerException从何而来?,java,nullpointerexception,ternary-operator,Java,Nullpointerexception,Ternary Operator,我试图编写一个方法,将一个两位数的数字转换为2000+的数字,返回所有其他数字的原样,并在将null作为参数传递时返回null 此实现按预期工作 private Integer convertTo4Digits(Integer modelYear) { boolean isTwoDigit = modelYear != null && modelYear < 100; if (isTwoDigit) { return 2000 + model
private Integer convertTo4Digits(Integer modelYear) {
boolean isTwoDigit = modelYear != null && modelYear < 100;
if (isTwoDigit) {
return 2000 + modelYear;
} else {
return modelYear;
}
}
private Integer convertto4数字(整型年份){
布尔值isTwoDigit=modelYear!=null&&modelYear<100;
如果(数字){
返回2000+车型年;
}否则{
回归模型年;
}
}
但是,当使用NULL调用时,这个函数在return语句中使用NPE失败
private Integer convertTo4Digits(Integer modelYear) {
return (modelYear != null && modelYear < 100) ? (2000 + modelYear) : modelYear;
}
private Integer convertto4数字(整型年份){
返回(modelYear!=null&&modelYear<100)?(2000+modelYear):modelYear;
}
还是这是一只虫子?我将EclipseKeple与JDK1.7.0_04一起使用,噢,该死,这一个很有效(注意显式转换为整数):
(modelYear!=null&&modelYear<100)?(整数)(2000+车型年款):车型年款;
问题是:三元运算符的第一个分支决定了问题版本中运算符的结果类型:int
现在modelYear(null)被取消装箱,这导致NPE在再次装箱之前就被取消装箱。我想答案可以在 如果第二个和第三个操作数中的一个是基元类型T,而另一个的类型是对T应用装箱转换(§5.1.7)的结果,则条件表达式的类型是T 因此,当第二个或第三个操作数是基元类型时,表达式的类型是基元类型。因此,如果您传递一个
null
引用,则将执行分支:modelYear
。但是,由于一个操作数是基元,因此必须取消绑定。这导致了NPE
如果查看生成的字节码,也可以看到这一点
private convertTo4Digits(Ljava/lang/Integer;)Ljava/lang/Integer;
L0
LINENUMBER 46 L0
ALOAD 1
IFNULL L1
ALOAD 1
INVOKEVIRTUAL java/lang/Integer.intValue()I
BIPUSH 100
IF_ICMPGE L1
SIPUSH 2000
ALOAD 1
INVOKEVIRTUAL java/lang/Integer.intValue()I
IADD
GOTO L2
L1
LINENUMBER 47 L1
ALOAD 1
INVOKEVIRTUAL java/lang/Integer.intValue()I
L2
LINENUMBER 46 L2
INVOKESTATIC java/lang/Integer.valueOf(I)Ljava/lang/Integer;
ARETURN
您自己的答案解决了这个问题,因为您正在将第二个操作数强制转换为Integer
(modelYear != null && modelYear < 100) ? (Integer) (2000 + modelYear) : modelYear;
(modelYear!=null&&modelYear<100)?(整数)(2000+车型年款):车型年款;
因此,第二个或第三个操作数都不是基元类型。因此,我在上面发布的JLS规则没有应用,NPE也没有了。也许问题应该改为
为什么三元运算符会导致NullPointerException?
更具解释性
(modelYear != null && modelYear < 100) ? (Integer) (2000 + modelYear) : modelYear;