我的开发问题记录里有这么一个问题,当时项目着急就没用三目,也没查找原因,那时的bean.getCounter()返回值也不知道是啥了,没有关系,咱们彻底分析一下这个问题。
// 三目失效 String counter = bean.getCounter() == "1" ? "第一次" : "第二次";
1.认识三目运算符
三目运算符,官方英文名称:Conditional Operator ? : 中文直译条件表达式。三目运算符的基本用法非常简单,它由三个操作数的运算符构成,形式为:
<表达式 1>?<表达式 2>:<表达式 3>
- 三目运算符从左往右计算,首先计算表达式 1 ,其结果类型必须为 Boolean 或 boolean,否则发生编译错误。
- 当表达式 1 的结果为 true,将会执行表达式 2,否则将会执行表达式 3。
- 表达式 2 与表达式 3 最后的类型必须得有返回结果,即不能为是 void,若为 void ,编译时将会报错。
- 最后需要注意的是,表达式 2 与表达式 3 不会被同时执行,两者只有一个会被执行。
2.三目运算符使用规范
以下是阿里巴巴Java开发手册泰山版对三目使用规范的描述:
第一种情况:
三目运算符表达式发生自动拆箱,官方在 「The Java Language Specification(简称:JLS)」15.25 节[1]中做出一些规定,部分内容如下:
# JDK7 规范 If the second and third operands have the same type (which may be the null type), then that is the type of the conditional expression. If one of the second and third operands is of primitive type T, and the type of the other is the result of applying boxing conversion (§5.1.7) to T, then the type of the conditional expression is T.
翻译一下:如果表达式 2 与表达式 3 类型相同,那么这个不用任何转换,三目运算符表达式结果当然与表达式 2,3 类型一致。当表达 2 或表达式 3 其中任一一个是基本数据类型,比如 int,而另一个表达式类型为包装类型,比如 Integer,那么三目运算符表达式结果类型将会为基本数据类型,即int。
第二种情况:
Otherwise, binary numeric promotion (§5.6.2[2]) is applied to the operand types, and the type of the conditional expression is the promoted type of the second and third operands. Note that binary numeric promotion performs value set conversion (§5.1.13[3]) and may perform unboxing conversion (§5.1.8[4]).
翻译一下:当表达式 2 与表达式 3 类型不一致,但是都为数字类型时,低范围类型将会自动转为高范围数据类型,即向上转型。这个过程将会发生自动拆箱。
3.三目失效问题分析
为了写这篇文章,我敲了多个demo反复测试,想要复现当时的问题,各种尝试最终都失败了,我猜测当时出现失效现象的可能原因是表达式1,测试的时候我也是在表达式1上反复做文章,发现做不出文章来(掩面泪目)。
4.总结
三目看似简单,还是有坑的,就像运算符的短路机制,不知道的时候都是泪。