小心! Java三目运算符

Double a = null;
double b = 0;
Scanner in = new Scanner(System.in);
boolean t = in.next().equals("y");
System.out.println(t ? a : b);

执行上述代码, 如果t为true则会抛出NPE, 执行javap查看反编译结果如图

可以看到54行执行了一次拆箱操作, 所以以下两行代码是等价的

t ? a : b
t ? a.doubleValue() : b

所以如果a = null, 当t=true会报NPE.

那么为什么好好的要拆箱呢? 以下是三目运算符表达式返回结果的规则:
首先将操作数的类型分为四种: 基础类型, 包装类型, null类型, object类型(不包括包装类型和null类型).

  1. 如果操作数一个为基础类型, 一个为包装类型, 则表达式返回值必为基础类型. 以下几种情况都需要考虑拆箱的问题.
    1. 操作数一个是基础类型, 另一个是其包装类型, 则返回该基础类型, 如 double = boolean ? Double : double;
    2. 操作数一个是基础类型, 另一个是其他基础类型的包装类型, 则返回表示范围更大的基础类型, 如 double = boolean ? Doubel : long;
    3. 操作数A是byte, char, short, 或者其包装类型, 另一个是数字常量(int), 则返回值返回A的类型的基础类型, 如 char = boolean ? char : 11;
  2. 如果操作数一个为基础类型或者包装类型, 另一个为null类型, 则表达式返回值必为包装类型. 如 Long = boolean ? long : null; 如果使用基础类型去接返回值则需要考虑拆箱问题
  3. 如果操作数一个为object类型, 则表达式返回值必为object类型. object = boolean ? long : object;

参考链接

注: 链接中的名词解释

bnp: bnp(…) means to apply binary numeric promotion; 我理解就是数字类型小范围像大范围的转换, 比如int -> double

T | bnp(…): The form “T | bnp(…)” is used where one operand is a constant expression of type int and may be representable in type T, where binary numeric promotion is used if the operand is not representable in type T

这里就是说, 如果一个操作数是常量的情况的话就取T, 否则按照bnp的规则处理.

lub: 解释文档 The least upper bound, or “lub”, of a set of reference types is a shared supertype that is more specific than any other shared supertype (that is, no other shared supertype is a subtype of the least upper bound). This type, lub(U1, …, Uk), is determined as follows.

If k = 1, then the lub is the type itself: lub(U) = U;

最小上界, lub(U1, U2) 结果就是U1和U2的公共父类中距离它俩最近的一个. 所以lub(U1) = U1, 特殊的null, lub(null, U1) = U1.

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值