Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why is my char printing as a number instead of a character?

Tags:

java

char

int

As per the Java ternary operator expression ? statement1 : statement2, if expression is 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 am expecting it to print y but its printing 121, why?

EDIT As per the manouti answer, the compiler interprets as int, but if that is the case then why I am seeing dead code at i?

If I do System.out.print(false ? 0 : x); then I am getting y, so why in this case doesn't the compiler interpret as int?

like image 355
rocking Avatar asked Jun 10 '15 17:06

rocking


People also ask

Why do I type numbers instead of letters on my laptop?

As a result, if you hit the Num Lock key by accident on a laptop, you might have a problem that looks like this. In this case, you’re typing numbers instead of letters because the Num Lock key is turned on. Here’s how to turn it off. The first step to turning off Num Lock is to find the Num Lock key on your laptop’s keyboard.

Why do symbols appear when I press the number keys?

Left or right shift key being stuck is one of the primary causes behind symbols appearing when you press the number keys on the keyboard. As the shift modifier replaces numbers with symbols in most keyboard layouts (including US layout), the key being stuck without you noticing would cause symbols to appear instead of numbers.

Which method is used to print the ASCII value of Y?

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

How do you make a character appear on the screen?

You press a key, and the character that is bound to that key appears on the screen. When you think about it, there isn’t much that can go wrong with such a simple mechanism.


2 Answers

121 is the 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 changing to System.out.print(false ? (char)i : y); prints y.

like image 92
M A Avatar answered Nov 15 '22 06:11

M A


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

So really your question boils down to, why does the type of the conditional expression differ between

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 that, we'll need to take a look at section §15.25 of the Java Language Specification.

There are three types of conditional expression in Java:

  • Boolean Conditional Expressions
  • Numeric Conditional Expressions
  • Reference Conditional Expressions

Since both int and char are convertible to a numeric type, the expression is an example of a numeric conditional expression according to this rule:

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

For the purpose of classifying a conditional, the following expressions are numeric expressions:

  • An expression of a standalone form (§15.2) with a type that is convertible to a numeric type (§4.2, §5.1.8).

Given that, the rule for determining the type of the entire expression is given as follows:

15.25.2. Numeric Conditional Expressions

Numeric conditional expressions are standalone expressions (§15.2).

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.

  • If one of the second and third operands is of primitive type T, and the type of the other is the result of applying boxing conversion (§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 type of the conditional expression is short.

  • 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.

  • 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 representable in the type U which is the result of applying unboxing conversion to T, then the type of the conditional expression is U.

  • 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 value set conversion (§5.1.13) and may perform unboxing conversion (§5.1.8).

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

However when you instead pass in a variable instead of a constant, you fall down to the last rule which says that "...the type of the conditional expression is the promoted type of the second and third operands."

If you take a look at section §5.6.2 of the JLS, it describes the rules for type promotion as follows:

When an operator applies binary numeric promotion to a pair of operands, each of which must denote a value that is convertible to a numeric type, the following rules apply, in order:

  1. If any operand is of a reference type, it is subjected to unboxing conversion (§5.1.8).

  2. 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.

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

like image 36
azurefrog Avatar answered Nov 15 '22 06:11

azurefrog