开发者

Output different from what i have expected

Why its printing X88

public static开发者_JAVA技巧 void main(String [] args)
{
      char x = 'X';
      int i = 0;
      System.out.print(true  ? x : 0);
      System.out.print(false ? i : x);
}


In the first print statement, the type of the conditional expression is char (i.e. 'X') because this part of section 15.25 of the JLS (which is about the type of a conditional expression) applies:

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

So the first statement prints "X".

In the second print statement, that part doesn't apply because i isn't a constant expression. Instead, this section applies:

Otherwise, 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. Note that binary numeric promotion performs unboxing conversion (§5.1.8) and value set conversion (§5.1.13).

Binary numeric promotion converts the char 'X' to an int (88) and the second statement prints "88" - hence the overall result of "X88".


It's explained in §15.25 of the JLS.

Otherwise, if the second and third operands have types that are convertible (§5.1.8) to numeric types, then there are several cases:

This applies to both statements, since both char and int are numeric types, and thus 5.1.8 trivially applies. So we look at the rules below (excerpted):

[...]

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

This applies to the first, since 0 is a constant expression of type int. T is , char, which is why it prints as X.

[...]

  • Otherwise, 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. Note that binary numeric promotion performs unboxing conversion (§5.1.8) and value set conversion (§5.1.13).

This applies to the second, since nothing else does. :) The relevant rule from §5.6.2 is simply:

Otherwise, both operands are converted to type int.

The Unicode code point for 'X' is 88.


For the first statement System.out.print(false ? x : 0); the compiler thinks that you want to print a char so 0 will be considered as a char (during compilation).

When you do System.out.print(false ? i : x); the compiler thinks that you want to print an integer, so it will try to convert (widen) 'X' into an integer which is 88.

An interesting thing is that if you try to do this :

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

As i cannot be considered as a char (it would require narrowing) it will print 88

Another thing which is interessant here :

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

This time the value 65536 can't be considered as a char at compile time (the max value for a char is 65535 [@See Character.MAX_VALUE]) so it will be considered as an int, so x will be too.


To summarize, if one of the operand is an int and the other a char, there are two possible conversions :

  1. The int is narrowed into a char (loss of precision)
  2. The char is widen into an int (no loss of precision)

To avoid useless loss, Java will chose the second option.

When you do System.out.print(false ? x : 0);, the 0 is converted at compilation time into a char (because the compiler knows that there won't be loss of precision).


Resources :

  • JLS - Widening Primitive Conversion


Because the expression false ? i : x is being seen as returning an integer by the compiler. Since you are using a char the 'X' is 88 in ASCII and it is being seen as an integer since they are compatible.

Personally, I think there should be at least a compiler warning here.


In the second ternary If, the parameters must be of the same type, otherwise one of the two is implicitly converted.

In your example, x is converted from char to int, and 'X' has an ASCII code of 88.


Others have already answered why this happens.

If you want X to be printed, cast the expression value back to char as:

System.out.print((char)(false ? i : x)); // prints X

or you can also cast i to char so that the type of expression becomes char as:

System.out.print(false ? (char)i : x); // prints X
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜