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

时间:2015-06-10 17:36:43

标签: java char int

根据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

3 个答案:

答案 0 :(得分:10)

121是字符y的整数表示。由于您在表达式中提供了i,因此编译器会将其解释为对System.out.print(int)而不是System.out.print(char)的调用。

请注意,更改为System.out.print(false ? (char)i : y);会打印y

答案 1 :(得分:3)

您问题的简短回答是打印的值基于条件表达式求值的类型。

所以你的问题归结为,为什么条件表达式的类型在

之间有所不同
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中有三种类型的条件表达式:

  • 布尔条件表达式
  • 数字条件表达式
  • 参考条件表达式

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

  

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

     

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

     
      
  • 独立形式(第15.2节)的表达式,其类型可转换为数字类型(§4.2,§5.1.8)。
  •   

鉴于此,确定整个表达式类型的规则如下:

  

<强> 15.25.2。数字条件表达式

     

数字条件表达式是独立表达式(第15.2节)。

     

数字条件表达式的类型确定如下:

     
      
  • 如果第二个和第三个操作数具有相同的类型,那么这就是条件表达式的类型。

  •   
  • 如果第二个和第三个操作数之一是原始类型T,而另一个操作数的类型是将装箱转换(第5.1.7节)应用于T的结果,那么条件表达式的类型是吨。

  •   
  • 如果其中一个操作数的类型为字节或字节,另一个操作数的类型为short或Short,则条件表达式的类型很短。

  •   
  • 如果其中一个操作数是T类型,其中T是byte,short或char,另一个操作数是int类型的常量表达式(第15.28节),其值可以在类型T中表示,那么条件表达式的类型是T.

  •   
  • 如果其中一个操作数是T类型,其中T是Byte,Short或Character,另一个操作数是int类型的常量表达式,其值可以在U类型中表示,它是U的结果。将取消装箱转换应用于T,则条件表达式的类型为U。

  •   
  • 否则,二进制数字提升(第5.6.2节)将应用于操作数类型,条件表达式的类型是第二个和第三个操作数的提升类型。

  •   
     

请注意,二进制数字促销执行值集转换(第5.1.13节)并可执行拆箱转换(第5.1.8节)。

请注意,第四条规则准确描述了第二个例子;第二个操作数是int0)类型的常量,第三个是char,因此条件表达式将计算为char。这将导致编译器使用print(char)方法,该方法将打印y

但是,当您改为传入变量而不是传递常量时,您会倒入最后一条规则,即“......条件表达式的类型”是第二和第三个操作数的提升类型。“

如果您查看section §5.6.2 of the JLS,它会按如下方式描述类型提升的规则:

  

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

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

  2.   
  3. 应用扩展基元转换(第5.1.2节)来转换由以下规则指定的一个或两个操作数:

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

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

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

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

    •   
  4.   

通过遵循这些规则,表达式的类型将为int,因此编译器将使用print(int)方法,该方法将打印121({{}}的ascii值1}})。

答案 2 :(得分:1)

121是 y 的ASCII代码,并且您已将 i 声明为整数,编译器也将 y 解释为int变量。因此,为 y 打印ASCII值。编写 System.out.print(false?(char)i:y)将打印 y