Skip to content

Java 解惑 -08:Dos Equis

🏷️ 《Java 解惑》

java
public class JavaPuzzlers008 {
    public static void main(String[] args) {
        char x = 'X';
        int i = 0;
        System.out.print(true ? x : 0);
        System.out.print(false ? i : x);
    }
}

这里是两个简单的问号冒号操作符。看起来都是打印两次变量 x 的值,也就是 XX ,但实际打印的确是 X88 。从结果来看第二个表达式被当做成了数值型。

混合类型的计算会引起混乱,而这一点在条件表达式中比在其他任何地方都表现的更明显。

确定条件表达式结果类型的规则过于冗长和复杂,很难完全记住它们,但是其核心就是以下三点:

  1. 如果第二个和第三个操作数具有相同的类型,那么它就是条件表达式的类型。

  2. 如果一个操作数的类型是 TT 表示 byteshortchar,而另一个操作数是一个 int 类型的常量表达式,它的值可以用类型 T 表示,那么条件表达式的类型就是 T

  3. 否则,将对操作数类型进行二进制数字提升,而条件表达式的类型就是第二个和第三个操作数被提升之后的类型。

第一个表达式 true ? x : 0 中的第三个操作数 0int 类型的常量表达式,符合上面的第二点,所以条件表达式的类型是 char
第二个表达式 false ? i : x 中的第二个操作数是 int 类型的变量,符合上面的第三点,所以条件表达式的类型是操作数提升后的类型 int

调用 print 方法打印时,会根据参数类型的不同调用不同的重载,所以打印的结果也就不尽相同了。

使用 final 修饰符用于 i 的声明时,可以把 i 转变为一个常量表达式,从而打印 XX

总之,通常最好是在条件表达式中使用类型相同的第二和第三操作数