繁体   English   中英

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

[英]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中的条件表达式分为三种:

  • 布尔条件表达式
  • 数值条件表达式
  • 引用条件表达式

由于intchar都可以转换为数字类型,因此表达式是根据此规则的数字条件表达式的示例:

如果第二个和第三个操作数表达式都是数值表达式,则条件表达式为数值条件表达式。

为了对条件进行分类,以下表达式是数字表达式:

  • 独立形式(第 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 节,它描述了类型提升的规则如下:

当运算符将二进制数字提升应用于一对操作数时,每个操作数必须表示一个可转换为数字类型的值,以下规则依次适用:

  1. 如果任何操作数是引用类型,则它会进行拆箱转换(第 5.1.8 节)。

  2. 扩展原语转换(第 5.1.2 节)用于转换一个或两个操作数,如以下规则所指定:

    • 如果任一操作数的类型为 double,则另一个将转换为 double。

    • 否则,如果任一操作数的类型为 float,则另一个将转换为 float。

    • 否则,如果任一操作数的类型为 long,则另一个将转换为 long。

    • 否则,两个操作数都被转换为 int 类型。

通过遵循这些规则,表达式的类型将为int ,因此编译器将使用print(int)方法,该方法将打印121y的 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.

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