为什么我的字符打印为数字而不是字符?
Why is my char printing as a number instead of a character?
根据 Java 三元运算符 expression ? statement1 : statement2
,
如果 expression
为真则 statement1
将被执行,如果 expression
为假则 statement2
将被执行。
但是当我运行:
// some unnecessary codes not displaying
char y = 'y';
int i = 0;
System.out.print(false ? i : y);
我期待它打印 y
但它打印 121
,为什么?
编辑
根据 manouti 的回答,编译器解释为 int
,但如果是这种情况,那么为什么我在 i
?
处看到死代码
如果我做 System.out.print(false ? 0 : x);
那么我得到 y
,那么为什么在这种情况下编译器不解释为 int
?
121
是字符y
的整数表示。由于您提供了 i
作为表达式的一部分,因此编译器将其解释为对 System.out.print(int)
而不是 System.out.print(char)
.
的调用
请注意,更改为 System.out.print(false ? (char)i : y);
会打印 y
。
121 是 y 的 ASCII 代码,正如您已将 i 声明为整数,编译器将 y 解释为 也作为 int 变量。因此打印 y 的 ASCII 值。写作 System.out.print(false ? (char)i : y) 将打印 y。
对您问题的简短回答是,打印的值基于条件表达式求值的类型。
所以你的问题实际上归结为,为什么条件表达式的类型在
之间不同
char y = 'y';
int i = 0;
System.out.print(false ? i : y); // prints 121
和
char y = 'y';
System.out.print(false ? 0 : y); // prints y
要回答这个问题,我们需要看一下 section §15.25 of the Java Language Specification。
Java中有三种条件表达式:
- 布尔条件表达式
- 数值条件表达式
- 参考条件表达式
由于int
和char
都可以转换为数字类型,表达式是根据此规则的数字条件表达式的示例:
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.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).
注意第四条规则恰好描述了第二个例子;第二个操作数是 int
(0
) 类型的常量,第三个是 char
,因此条件表达式的计算结果为 char
。这将导致编译器使用 print(char)
方法,该方法将打印 y
.
然而,当您改为传入 变量 而不是 常量 时,您将落入最后一条规则,即“. ..条件表达式的类型是第二个和第三个操作数的提升类型。"
如果你看一下section §5.6.2 of the JLS,它描述了类型提升的规则如下:
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:
If any operand is of a reference type, it is subjected to unboxing conversion (§5.1.8).
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.
通过遵循这些规则,表达式的类型将为 int
,因此编译器将使用 print(int)
方法,该方法将打印 121
( y
).
根据 Java 三元运算符 expression ? statement1 : statement2
,
如果 expression
为真则 statement1
将被执行,如果 expression
为假则 statement2
将被执行。
但是当我运行:
// some unnecessary codes not displaying
char y = 'y';
int i = 0;
System.out.print(false ? i : y);
我期待它打印 y
但它打印 121
,为什么?
编辑
根据 manouti 的回答,编译器解释为 int
,但如果是这种情况,那么为什么我在 i
?
如果我做 System.out.print(false ? 0 : x);
那么我得到 y
,那么为什么在这种情况下编译器不解释为 int
?
121
是字符y
的整数表示。由于您提供了 i
作为表达式的一部分,因此编译器将其解释为对 System.out.print(int)
而不是 System.out.print(char)
.
请注意,更改为 System.out.print(false ? (char)i : y);
会打印 y
。
121 是 y 的 ASCII 代码,正如您已将 i 声明为整数,编译器将 y 解释为 也作为 int 变量。因此打印 y 的 ASCII 值。写作 System.out.print(false ? (char)i : y) 将打印 y。
对您问题的简短回答是,打印的值基于条件表达式求值的类型。
所以你的问题实际上归结为,为什么条件表达式的类型在
之间不同char y = 'y';
int i = 0;
System.out.print(false ? i : y); // prints 121
和
char y = 'y';
System.out.print(false ? 0 : y); // prints y
要回答这个问题,我们需要看一下 section §15.25 of the Java Language Specification。
Java中有三种条件表达式:
- 布尔条件表达式
- 数值条件表达式
- 参考条件表达式
由于int
和char
都可以转换为数字类型,表达式是根据此规则的数字条件表达式的示例:
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.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).
注意第四条规则恰好描述了第二个例子;第二个操作数是 int
(0
) 类型的常量,第三个是 char
,因此条件表达式的计算结果为 char
。这将导致编译器使用 print(char)
方法,该方法将打印 y
.
然而,当您改为传入 变量 而不是 常量 时,您将落入最后一条规则,即“. ..条件表达式的类型是第二个和第三个操作数的提升类型。"
如果你看一下section §5.6.2 of the JLS,它描述了类型提升的规则如下:
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:
If any operand is of a reference type, it is subjected to unboxing conversion (§5.1.8).
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.
通过遵循这些规则,表达式的类型将为 int
,因此编译器将使用 print(int)
方法,该方法将打印 121
( y
).