[英]Why is my char printing as a number instead of a character?
根据 Java 三元运算符expression ? statement1 : statement2
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
。
对您的问题的简短回答是打印的值基于条件表达式计算的类型。
所以真的你的问题归结为,为什么条件表达式的类型不同
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
要回答这个问题,我们需要查看Java 语言规范的第 15.25 节。
Java中的条件表达式分为三种:
由于int
和char
都可以转换为数字类型,因此表达式是根据此规则的数字条件表达式的示例:
如果第二个和第三个操作数表达式都是数值表达式,则条件表达式为数值条件表达式。
为了对条件进行分类,以下表达式是数字表达式:
- 独立形式(第 15.2 节)的表达式,其类型可转换为数字类型(第 4.2 节、第 5.1.8 节)。
鉴于此,确定整个表达式的类型的规则如下:
15.25.2. 数值条件表达式
数字条件表达式是独立的表达式(第 15.2 节)。
数值条件表达式的类型确定如下:
如果第二个和第三个操作数的类型相同,那就是条件表达式的类型。
如果第二个和第三个操作数之一是原始类型 T,另一个的类型是对 T 应用装箱转换(第 5.1.7 节)的结果,则条件表达式的类型为 T。
如果操作数之一是 byte 或 Byte 类型,另一个是 short 或 Short 类型,则条件表达式的类型为 short。
如果其中一个操作数是 T 类型,其中 T 是字节、短整型或字符,而另一个操作数是一个 int 类型的常量表达式(第 15.28 节),其值可在类型 T 中表示,则条件表达式的类型为T。
如果其中一个操作数是 T 类型,其中 T 是 Byte、Short 或 Character,而另一个操作数是一个 int 类型的常量表达式,其值可以用类型 U 表示,这是对 T 应用拆箱转换的结果,那么条件表达式的类型是 U。
否则,将二进制数值提升(第 5.6.2 节)应用于操作数类型,条件表达式的类型是第二个和第三个操作数的提升类型。
请注意,二进制数字提升执行值集转换(第 5.1.13 节)并可能执行拆箱转换(第 5.1.8 节)。
请注意,第四条规则准确地描述了第二个示例; 第二个操作数是int
( 0
) 类型的常量,第三个是char
,因此条件表达式的计算结果为char
。 这将导致编译器使用print(char)
方法,该方法将打印y
。
然而,当你传入一个变量而不是一个常量时,你会陷入最后一条规则,即“......条件表达式的类型是第二个和第三个操作数的提升类型”。
如果您查看JLS 的第 5.6.2 节,它描述了类型提升的规则如下:
当运算符将二进制数字提升应用于一对操作数时,每个操作数必须表示一个可转换为数字类型的值,以下规则依次适用:
如果任何操作数是引用类型,则它会进行拆箱转换(第 5.1.8 节)。
扩展原语转换(第 5.1.2 节)用于转换一个或两个操作数,如以下规则所指定:
如果任一操作数的类型为 double,则另一个将转换为 double。
否则,如果任一操作数的类型为 float,则另一个将转换为 float。
否则,如果任一操作数的类型为 long,则另一个将转换为 long。
否则,两个操作数都被转换为 int 类型。
通过遵循这些规则,表达式的类型将为int
,因此编译器将使用print(int)
方法,该方法将打印121
( y
的 ascii 值)。
121 是y 的ASCII 代码,因为您已将i声明为整数,编译器也将y解释为 int 变量。 因此打印y的 ASCII 值。 编写System.out.print(false ? (char)i : y)将打印y 。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.