java - 为什么这个 map 检索会产生 NPE?

标签 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);
        }       
    }
}

在循环的第二次迭代期间,在行 Float foo =... 上产生 NullPointerException:

A
0.0
B
Exception in thread "main" java.lang.NullPointerException
    at TestMap.main(TestMap.java:14)

如果我用下面的注释行替换现有行,它会按预期工作,分配 foo = null。为什么这两种情况下的行为不同?

最佳答案

键“B”的值为空。但是你的条件表达式的返回类型是一个 float (原语),因为你使用的是文字 0F,而不是 Float(包装器),所以这个值必须被自动拆箱(到一个原语)然后自动装箱(回到一个对象)。这导致 NPE。

比较使用时发生的情况

Float foo = (tm == null ? Float.valueOf(0f) : tm.get(key));

作为补充说明,这是您的条件正在执行的操作(显示明确的装箱):

Float foo;
float conditionalResult;

if ( tm == null ) {
    conditionalResult = 0F;
} else {
    conditionalResult = tm.get(key).floatValue(); //this throws the NPE
}
foo = Float.valueOf(conditionalResult);

JLS 15.25定义条件运算符的返回类型。它非常复杂,我发现通过实验更容易学习 :-)。

关于java - 为什么这个 map 检索会产生 NPE?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3814606/

相关文章:

java - 为什么我会收到此 NullPointerException?

java - Android 空指针异常 - fragment (PA4AD)

java - 将命令行参数传递给 spring 配置

java - 二叉搜索树 - 删除所有大于特定值的整数

java - 如何动态地将多个值添加到HashMap中的单个键上?

java - Clojure:动态导入java类

c++ - 如果在 NULL 指针取消引用之前使用,cout 似乎不起作用

java - 为什么我会得到空指针异常?

java - 无法将数据库数据填充到 jcombobox 中

java - 选择 : Migrating from Classic ASP to . NET 或迁移到开源平台