G__*_*G__ 4 java nullpointerexception
考虑这个课程:
public class TestMap extends HashMap<String, Float> {
public static void main(String[] args) {
TestMap tm = new TestMap();
tm.put("A", 0F);
tm.put("B", null);
String[] keys = new String[]{"A", "B"};
for (String key : keys) {
System.out.println(key);
Float foo = (tm == null ? 0F : tm.get(key));
// Float foo = tm.get(key);
System.out.println(foo);
}
}
}
Run Code Online (Sandbox Code Playgroud)
Float foo =...
在循环的第二次迭代期间在该行上生成NullPointerException :
A
0.0
B
Exception in thread "main" java.lang.NullPointerException
at TestMap.main(TestMap.java:14)
Run Code Online (Sandbox Code Playgroud)
如果我用下面的注释行替换现有行,它按预期工作,分配foo = null.为什么这两种情况的行为不同?
Mar*_*ers 17
The value for key "B" is null. But the return type of your conditional expression is a float (primitive) due to you using the literal 0F
, not a Float (wrapper), so the value has to be autounboxed (to a primitive) and then autoboxed (back to an object). This results in the NPE.
Compare to what happens when you use
Float foo = (tm == null ? Float.valueOf(0f) : tm.get(key));
Run Code Online (Sandbox Code Playgroud)
作为一个补充说明,这是你的条件正在做什么(显示明确拳击):
Float foo;
float conditionalResult;
if ( tm == null ) {
conditionalResult = 0F;
} else {
conditionalResult = tm.get(key).floatValue(); //this throws the NPE
}
foo = Float.valueOf(conditionalResult);
Run Code Online (Sandbox Code Playgroud)
JLS 15.25定义了条件运算符的返回类型.它非常复杂,我发现通过实验学习更容易:-).