What is the type of a ternary expression with int

2020-05-02 12:50发布

问题:

I recently come accross the scenario where in first syso() charcter is working fine but in second syso() it is printing ASCII code.

public class Test{
public static void main(String[] args) {
    char x = 'A';
    char y= 'B';
    int m = 0;

    System.out.println(true  ? x : 0);//Working fine prints A
    System.out.println(true  ? y : 0);//Working fine prints B
    System.out.println(false ? 0 : y);//Working fine prints B
    System.out.println(false ? m : x);// Here it prints 65 why ?
   }
 }

I really want to know why it is printing ascii code in second syso() ? Please help

回答1:

The issue is in the type of false ? m : x, which ends up being int, not char.

As per JLS section 15.25.2 (emphasis and [] note mine):

The type of a numeric conditional expression is determined as follows:

  • If the second and third operands have the same type, then that is the type of the conditional expression.

...

  • Otherwise [if none of the above rules hold], binary numeric promotion (§5.6.2) is applied to the operand types, and the type of the conditional expression is the promoted type of the second and third operands.

Where binary numeric promotion's relevant rule is (emphasis mine):

Widening primitive conversion (§5.1.2) is applied to convert either or both operands as specified by the following rules:

  • If either operand is of type double, the other is converted to double.

  • Otherwise, if either operand is of type float, the other is converted to float.

  • Otherwise, if either operand is of type long, the other is converted to long.

  • Otherwise, both operands are converted to type int.

Therefore in:

char x = ...;
int m = ...;

The expression condition ? m : x is promoted to int, and System.out.println(int) is called, and it prints it as a number.

You'd have to explicitly cast m or the whole expression to a char, e.g.:

System.out.println((char)(false ? m : x));

Or:

System.out.println(false ? (char)m : x);

As for your condition ? x : 0 and condition ? 0 : x forms, one of the rules (that I omitted above) from 15.25.2 is:

  • If one of the operands is of type T where T is byte, short, or char, and the other operand is a constant expression (§15.28) of type int whose value is representable in type T, then the type of the conditional expression is T.

0 fits this description. x is a char, 0 fits in a char, the type of the conditional is therefore char and the character is printed.