当前位置: 首页 > 面试题库 >

为什么三元运算会给nullpointer而ifelse却没有呢?[重复]

关正雅
2023-03-14
问题内容

我在下面的一个实例中得到了NullPointerException,而其对应实例运行平稳。

public static void main(String[] args){
    System.out.println(withTernary(null, null)); //Null Pointer
    System.out.println(withIfElse(null, null));  //No Exception
}

private static Boolean withTernary(String val, Boolean defVal){
    return val == null ? defVal : "true".equalsIgnoreCase(val);
}

private static Boolean withIfElse(String val, Boolean defVal){
    if (val == null) return defVal;
    else return "true".equalsIgnoreCase(val);
}

在线版

在线版本中的台词main相反,其输出nullwithIfElse,然后失败withTernary

我正在使用以下Java版本

java version "1.6.0_65"
Java(TM) SE Runtime Environment (build 1.6.0_65-b14-462-11M4609)
Java HotSpot(TM) 64-Bit Server VM (build 20.65-b04-462, mixed mode)

问题答案:

这是该规范的相关报价(第15.25.2节):

布尔条件表达式是独立表达式(第15.2节)。

布尔条件表达式的类型确定如下:

  • 如果第二和第三操作数均为type Boolean,则条件表达式的类型为Boolean

  • 否则,条件表达式的类型为boolean

因此,整个表达式的类型被认为是boolean,并且该Boolean值被自动取消装箱,从而导致NullPointerException

如评论中所述,以下内容为何不引发异常?

return val == null ? null : "true".equalsIgnoreCase(val);

好吧,以上摘自规范的摘要仅适用于
布尔条件表达式,在
此指定(第15.25节):

如果第二和第三操作数表达式都是 布尔表达式 ,则条件表达式是布尔条件表达式。

为了对条件进行分类,以下表达式是布尔表达式:

* 类型为或的独立形式(第15.2节)的表达式。boolean``Boolean

* 带括号的boolean表达式(第15.8.5节)。

* 类的类实例创建表达式(§15.9)Boolean

* 方法调用表达式(第15.12节),为其选择的最特定方法(第15.12.2.5节)具有返回类型booleanBoolean
(请注意,对于泛型方法,这是实例化方法的类型参数之前的类型。)

  • boolean条件表达式。

由于null不是 布尔表达式 ,因此整体条件表达式不是 布尔条件表达式。参见表15.2(在同一部分后面),我们可以看到这样的表达式被认为具有Boolean类型,因此不会发生拆箱,也不会引发异常。



 类似资料:
  • 但是我发现我不能用围棋做同样的事情,我必须写一个if-else语句。我只是想知道为什么在围棋世界里不存在这种情况(是否有一些设计原则来解释这种情况)

  • 问题内容: PostgreSQL文件说: SQL函数的整个主体在执行任何函数之前都会被解析。 虽然SQL函数可以包含 更改系统目录的命令 (例如),但是在对函数中的后续命令进行语法分析时,这些命令的效果将不可见。因此,例如, 如果打包到单个SQL函数中将无法按预期工作 ,因为解析命令时foo尚不存在。 在这种情况下,建议使用PL / pgSQL代替SQL函数。 为什么“在这种情况下,建议使用PL

  • 问题内容: 就是这样:https : //groups.google.com/forum/?fromgroups#!topic/golang- dev/Ab1sFeoZg_8 : 今天,我向垃圾收集器提交了更改,这些更改使典型的最坏情况下的世界停止时间小于100微秒。对于具有许多活动goroutine的应用程序,这应该尤其可以改善暂停时间,而以前可能会大大增加暂停时间。 如果JVM用户长期苦苦挣扎

  • 书上说这段代码在目录被glob匹配的情况下(如node_modules/fs.stat)应该报错,但是我在本地执行没有。 下面代码实现了一个copy的功能,将source directory下的所有文件复制到destination directory。 对这段代码的几点说明: 此处的glob版本为7.2.3,最新版本的glob是基于promise的,不再支持回调。 fs-extra提供了更多的功能

  • 问题内容: 在这段代码中,为什么使用结果为no 或循环捕获所有异常然后静默退出?在这种情况下,为什么会有多余的?还是由以下 原因引起的? 假设由触发。什么时候产生的? 如果我手动执行以下操作: 在这种情况下,为什么看不到追溯? 问题答案: 该循环监听明确。 该语句的目的是循环遍历迭代器提供的序列,并使用异常表示当前迭代器已完成。不会捕获被迭代的对象引发的其他异常,只是那个异常。 这是因为正常的预期