Why does my char print as a number instead of a character?

According to the triple operator Java expression ? statement1 : statement2 expression ? statement1 : statement2 , if expression true, then statement1 will be executed, if expression is false, then statement2 will be executed.

But when I run:

 // some unnecessary codes not displaying char y = 'y'; int i = 0; System.out.print(false ? i : y); 

I expect him to print y , but his print is 121 , why?

EDIT According to manuchi's answer, the compiler interprets as int , but if so, why am I seeing dead code in i ?

If I do System.out.print(false ? 0 : x); , then I get y , so why in this case the compiler does not interpret as int ?

+6
source share
3 answers

The short answer to your question is that the printed value is based on a type that evaluates to a conditional expression.

So your question comes down to why the type of conditional expression is different from

 char y = 'y'; int i = 0; System.out.print(false ? i : y); // prints 121 

and

 char y = 'y'; System.out.print(false ? 0 : y); // prints y 

To answer this question, we need to take a look at the §15.25 section of the Java language specification .

There are three types of conditional expression in Java:

  • Boolean conditional expressions
  • Numeric Conditional Expressions
  • Conditional conditional expressions

Since both int and char converted to a numeric type, the expression is an example of a numeric conditional expression in accordance with this rule:

If both the second and third expressions of the operand are numerical expressions, the conditional expression is a numerical conditional expression.

In order to classify a conditional expression, the following expressions are numerical expressions:

  • An autonomous form expression (§15.2) with a type that is converted to a numerical type (§4.2, § 5.1.8).

Given that the rule for determining the type of the whole expression is defined as follows:

15.25.2. Numeric Conditional Expressions

Numeric conditional expressions are autonomous expressions (§15.2).

The type of numerical conditional expression is defined as follows:

  • If the second and third operands are of the same type, then this is a conditional expression type.

  • If one of the second and third operands has a primitive type T, and the type of the other is the result of applying the conversion of the box (section 5.1.7) to T, then the type of the conditional expression is T.

  • If one of the operands is of type byte or byte, and the other is of type short or Short, then the conditional expression type is short.

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

  • If one of the operands is of type T, where T is Byte, Short, or Character, and the other operand is a constant expression of type int, whose value is represented in type U, which is the result of applying unboxing to T, then the conditional expression type is equal to U.

  • Otherwise, binary numeric promotion (§5.6.2) is used for operand types, and the conditional expression type is the advanced type of the second and third operands.

Note that binary numeric promotion performs a conversion on a set of values ​​(§5.1.13) and can perform conversion for unpacking (§5.1.8).

Note that the fourth rule accurately describes the second example; the second operand is a constant of type int ( 0 ), and the third is char , so the conditional expression will evaluate to char . This will force the compiler to use the print(char) method, which will print y .

However, when you instead pass a variable instead of a constant, you come to the last rule, which states that "... the type of conditional expression is an advanced type of the second and third operands."

If you look at Section §5.6.2 of the JLS , it describes type promotion rules as follows:

When an operator applies binary numeric promotion to a pair of operands, each of which must indicate a value that can be converted to a numeric type, the following rules apply to:

  • If any operand has a reference type, it undergoes unpacking of the transformation (section 5.1.8).

  • The primitive conversion extension (§5.1.2) is used to convert one or both operands, as specified in the following rules:

    • If one of the operands 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 int type.

Following these rules, the type of the expression will be int , so the compiler will use the print(int) method, which will print 121 (ascii y value).

+3
source

121 is an integer representation of the character y . Since you provided i as part of the expression, the compiler interprets it as a call to System.out.print(int) instead of System.out.print(char) .

Note that switching to System.out.print(false ? (char)i : y); prints y .

+10
source

121 is the ASCII code for y , and since you declared i as an integer, the compiler interprets y as an int variable. Thus, printing the ASCII value for y . Writing System.out.print (false? (Char) i: y) will print y .

+1
source

Source: https://habr.com/ru/post/988864/


All Articles