简体   繁体   English

为什么我的字符打印为数字而不是字符?

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

As per the Java ternary operator expression ? statement1 : statement2根据 Java 三元运算符expression ? statement1 : statement2 expression ? statement1 : statement2 , if expression is true then statement1 will be executed, if expression is false then statement2 will be executed. expression ? statement1 : statement2 ,如果expression为真则执行statement1 ,如果expression为假则执行statement2

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?我期待它打印y但它打印121 ,为什么?

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 ?编辑根据 manouti 的答案,编译器解释为int ,但如果是这种情况,那么为什么我在i看到死代码?

If I do System.out.print(false ? 0 : x);如果我做System.out.print(false ? 0 : x); then I am getting y , so why in this case doesn't the compiler interpret as int ?然后我得到y ,那么为什么在这种情况下编译器不解释为int

121 is the integer representation of the character y . 121是字符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) .由于您提供i作为表达式的一部分,编译器将其解释为对System.out.print(int)而不是System.out.print(char)的调用。

Note that changing to System.out.print(false ? (char)i : y);请注意,更改为System.out.print(false ? (char)i : y); prints y .打印y

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 .要回答这个问题,我们需要查看Java 语言规范的第 15.25 节

There are three types of conditional expression in Java: 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:由于intchar都可以转换为数字类型,因此表达式是根据此规则的数字条件表达式的示例:

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).独立形式(第 15.2 节)的表达式,其类型可转换为数字类型(第 4.2 节、第 5.1.8 节)。

Given that, the rule for determining the type of the entire expression is given as follows:鉴于此,确定整个表达式的类型的规则如下:

15.25.2. 15.25.2. Numeric Conditional Expressions数值条件表达式

Numeric conditional expressions are standalone expressions (§15.2).数字条件表达式是独立的表达式(第 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.如果第二个和第三个操作数之一是原始类型 T,另一个的类型是对 T 应用装箱转换(第 5.1.7 节)的结果,则条件表达式的类型为 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.如果操作数之一是 byte 或 Byte 类型,另一个是 short 或 Short 类型,则条件表达式的类型为 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.如果其中一个操作数是 T 类型,其中 T 是字节、短整型或字符,而另一个操作数是一个 int 类型的常量表达式(第 15.28 节),其值可在类型 T 中表示,则条件表达式的类型为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.如果其中一个操作数是 T 类型,其中 T 是 Byte、Short 或 Character,而另一个操作数是一个 int 类型的常量表达式,其值可以用类型 U 表示,这是对 T 应用拆箱转换的结果,那么条件表达式的类型是 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.否则,将二进制数值提升(第 5.6.2 节)应用于操作数类型,条件表达式的类型是第二个和第三个操作数的提升类型。

Note that binary numeric promotion performs value set conversion (§5.1.13) and may perform unboxing conversion (§5.1.8).请注意,二进制数字提升执行值集转换(第 5.1.13 节)并可能执行拆箱转换(第 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 .第二个操作数是int ( 0 ) 类型的常量,第三个是char ,因此条件表达式的计算结果为char This will cause the compiler to use the print(char) method, which will print y .这将导致编译器使用print(char)方法,该方法将打印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:如果您查看JLS 的第 5.6.2 节,它描述了类型提升的规则如下:

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).如果任何操作数是引用类型,则它会进行拆箱转换(第 5.1.8 节)。

  2. Widening primitive conversion (§5.1.2) is applied to convert either or both operands as specified by the following rules:扩展原语转换(第 5.1.2 节)用于转换一个或两个操作数,如以下规则所指定:

    • If either operand is of type double, the other is converted to double.如果任一操作数的类型为 double,则另一个将转换为 double。

    • Otherwise, if either operand is of type float, the other is converted to float.否则,如果任一操作数的类型为 float,则另一个将转换为 float。

    • Otherwise, if either operand is of type long, the other is converted to long.否则,如果任一操作数的类型为 long,则另一个将转换为 long。

    • Otherwise, both operands are converted to type int.否则,两个操作数都被转换为 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 ).通过遵循这些规则,表达式的类型将为int ,因此编译器将使用print(int)方法,该方法将打印121y的 ascii 值)。

121 is ASCII code for y and as you have declared i as an integer, the compiler interprets y as int variable too. 121 是y 的ASCII 代码,因为您已将i声明为整数,编译器也将y解释为 int 变量。 Thus printing an ASCII value for y .因此打印y的 ASCII 值。 Writing System.out.print(false ? (char)i : y) will print y .编写System.out.print(false ? (char)i : y)将打印y

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM