Puzzle 8: Dos Equis

条件运算符的迷思

本主题用到的代码片段如下:

char x = 'X';

int i = 0;

System.out.print(true ? x : 0);

System.out.print(false ? i : x);

哈,应输出XX吧,不对,输出的是X88.

按照JLS 15.25的说法,在Java中,条件运算符的返回类型包含但不限于如下规则:

假设第二个和第三个操作数是可以转化的数字型,并且其中一个操作数是byte/char/int,

  • 如果另一个操作数和这个操作数同型,返回类型就是它们的类型。
  • 如果另一个操作数是int型常量,那么,如果这个int型常量能等值转化为另一个操作数的类型(byte/char/int),则返回值是byte/char/int。这就解释了前面true ? x : 0为什么返回的是X的问题,因为int型常量0可以等值转化为char型。试试换成System.out.print(true ? x : 72222222);输出的就成了88了,因为72222222不能等值转化为char型。
  • 如果另一个数是int型的,但不是常量,那么,对不起,返回值就按照JLS 5.6.2的来做。

另外,如果要输出XX的话,把上面的int i = 0;定义成final变量也可以的,不过这样还是非常的confusing。所以Java Puzzler曰,当用到条件运算表达式时,最好让第二和第三操作数同型。

没想到这个条件运算符的返回值规则的内容在JSL中写了那么多,详情将参照附1的link随后补上(TODO)。

  1. JLS 5.6.2 Binary Numeric Promotion
  2. JLS 15.25 Conditional Operator ? :
  3. Puzzle 5: 不同型的数参与一个运算总是很confusing的。
  4. TODO 书中P20到P21的一部分内容没搞懂,需要再读一下。