当前位置: 首页 > 知识库问答 >
问题:

空指针异常而不是空(JVM错误?)

周和歌
2023-03-14

我在当前版本的Java8中发现了一个奇怪的行为。在我看来,下面的代码应该可以,但是JVM抛出了一个NullPointerException

Supplier<Object> s = () -> false ? false : false ? false : null;
s.get(); // expected: null, actual: NullPointerException

这并不重要,它是什么样的lambda表达式(与java.util.function.Function相同)或使用了什么泛型类型。也可以用更有意义的表达式来代替false?:。上面的例子很短。这里有一个更丰富多彩的例子:

Function<String, Boolean> f = s -> s.equals("0") ? false : s.equals("1") ? true : null;
f.apply("0"); // false
f.apply("1"); // true
f.apply("2"); // expected: null, actual: NullPointerException

然而,这些代码段运行良好:

Supplier<Object> s = () -> null;
s.get(); // null

Supplier<Object> s = () -> false ? false : null;
s.get(); // null

或与功能:

Function<String, Boolean> f = s -> {
    if (s.equals("0")) return false;
    else if (s.equals("1")) return true;
    else return null;
};
f.apply("0"); // false
f.apply("1"); // true
f.apply("2"); // null

我测试了两个Java版本:

~#java-版本

openjdk版本“1.8.0_66-internal”openjdk运行时环境(构建1.8.0_66-internal-b01)openjdk 64位服务器虚拟机(构建25.66-b01,混合模式

C:\

java版本“1.8.0_51”java(TM)SE运行时环境(构建1.8.0_51-b16)java热点(TM)64位服务器虚拟机(构建25.51-b03,混合模式)


共有1个答案

从光启
2023-03-14

这与lambda表达式无关;只是在这种情况下,三元运算符的返回类型是boolean,因此将使用自动取消装箱。

NPE也扔在这里:

public class Main {

    private static Object method() {
        return false ? false : false ? false : null;
    }

    public static void main(String[] args) {
        System.out.println(method());
    }
}

那么,这里到底发生了什么?

首先,根据JLS§15.25评估“嵌入”表达式(false?false:null):

条件运算符在语法上是右关联的(它从右到左分组)。因此,a?B: c?D: e?f: g的意思和a一样?B:(c?D:(e?f: g))。

嵌入表达式的类型是布尔表达式(装箱的布尔表达式),因此可以将false和null表达式放入其中。

那么整个表达就是:

false ? false : (Boolean expression)

然后,再次根据JLS§15.25:

如果第二个和第三个操作数中的一个是基元类型T,而另一个的类型是对T应用装箱转换(§5.1.7)的结果,则条件表达式的类型是T。

因此,第一个参数是基本类型booleanT,在规范中),另一个参数是装箱的Tboolean),因此整个表达式的类型是boolean

然后,在运行时,嵌入表达式的计算结果为null,该值自动取消绑定为布尔值,从而导致NPE。

 类似资料:
  • 问题内容: 有可能这可能是一个双重问题。我将String变量初始化为null。我可能会或可能不会使用一个值更新它。现在我想检查此变量是否不等于null以及我尝试执行的操作是否会得到null指针异常。空指针异常,因为它代价高昂。是否有任何有效的解决方法.TIA 问题答案: 如果您使用 你 不会 得到。 我怀疑你在做什么: 这是因为null 而引发,而不是因为null。 如果仍然无法解释,请发布您用于

  • 我已经更新了我的项目中的一些依赖关系之后,我的Hibernate配置类显示Nullpointerx的。 我将SpringDataJPA存储库与hibernate一起使用,已经超过24小时了,仍然没有找到任何关于小问题的适当解决方案。 我已经尝试过的一些解决方案:- 使用@bean(name=“entityManagerFactory”)提供bean名称 我面临的问题 波姆。xml文件 配置类 db

  • 问题内容: 我正在继续我的上学项目,似乎遇到了另一个错误。所以发生的事情基本上是我收到一个空指针异常,即使代码看起来很好。我相信我的阵列出了点问题,即使经过数小时的搜索,我似乎也找不到该错误。再一次,任何帮助/解决方案将不胜感激。 } 我有一个带有构造函数的学生班,并且有一个说明 但仍然出现错误。我知道要处理的代码很多,因此再次感谢任何帮助。 问题答案: 由于您的代码是当前编写的, 由于您永远不会

  • 当我试图从DB查询结果时,我得到一个空指针异常。以下是错误: 这是错误产生的函数。 如果我启动应用程序信息服务(=new ApplicationInfoService()),我会得到一个指向我的服务类的空指针错误,在这里进行查询 错误转到createQuery行,如果我打印出EntityManager,它将返回“null”。为什么我的Entitymanager不能初始化。我在我的登录系统中使用了几

  • 因此,我必须创建一个方法,将输入字符串分成名字/中间名/姓氏,计算创建的“学生”的数量,等等,然后我必须创建测试这些方法的类。 这是我测试代码的方式: } 当它为具有2个名称的学生测试toString时,我一直遇到空指针异常,我不知道为什么。

  • 问题内容: 嗨,我们一直在使用apache编写我们的Java程序来读取xls和xlsx文件,问题是我们由于两个原因而得到了空指针异常。第一个是已经解决的空白单元格,另一个是当我们选择一个没有任何记录的列。 我们的程序要求输入excel文件的路径,然后输入要读取的文件的特定工作表号和特定的工作表的列号。这是读取xls文件的代码 变量工作表名称用于excel文件的工作表编号 变量cols用于您要阅读的