输出与我的预期不同

时间:2010-10-02 07:03:27

标签: java

为什么打印X88

public static void main(String [] args)
{
      char x = 'X';
      int i = 0;
      System.out.print(true  ? x : 0);
      System.out.print(false ? i : x);
}

6 个答案:

答案 0 :(得分:5)

在第一个print语句中,条件表达式的类型是char(即'X'),因为section 15.25 of the JLS的这一部分(大约是条件表达式的类型)适用:< / p>

  

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

所以第一个语句打印“X”。

在第二个print语句中,该部分不适用,因为i 不是常量表达式。相反,本节适用:

  

否则,二进制数字提升(§5.6.2)将应用于操作数类型,条件表达式的类型是第二个和第三个操作数的提升类型。请注意,二进制数字促销执行拆箱转换(第5.1.8节)和值集转换(第5.113节)。

二进制数字提升将char'X'转换为int(88),第二个语句打印“88” - 因此“X88”的整体结果。

答案 1 :(得分:4)

在JLS的§15.25中对此进行了解释。

  

否则,如果是第二个和第三个   操作数有类型   可转换(第5.1.8节)到数字类型,   那么有几种情况:

这适用于两个语句,因为char和int都是数字类型,因此5.1.8非常适用。所以我们看下面的规则(摘录):

  

[...]

     
      
  • 如果其中一个操作数是T类型,其中T是byte,short或   char,另一个操作数是   int类型的常量表达式   值可以在类型T中表示   条件表达式的类型   是T。
  •   

这适用于第一个,因为0是int类型的常量表达式。 T是,char,这就是它打印为X的原因。

  

[...]

     
      
  • 否则,二进制数字促销(§5.6.2)将应用于   操作数类型和类型   条件表达式是升级的   第二个和第三个操作数的类型。   注意二进制数字促销   执行拆箱转换(§5.1.8)   和价值集转换(第5.113节)。
  •   

这适用于第二个,因为没有别的。 :)来自§5.6.2的相关规则很简单:

  

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

'X'的Unicode代码点是88。

答案 2 :(得分:1)

对于第一个语句System.out.print(false ? x : 0);,编译器认为您要打印一个char,因此0将被视为char(在编译期间)。

执行System.out.print(false ? i : x);时,编译器认为您要打印一个整数,因此它会尝试将(加宽)'X'转换为88的整数。

有趣的是,如果你尝试这样做:

System.out.print(true ? x : i);

由于i不能被视为一个字符(它需要缩小),它将打印88

另一件令人沮丧的事情是:

System.out.print(true  ? x : 65536);

这次在编译时不能将值65536视为char(char的最大值为65535 [@See Character.MAX_VALUE])因此它将被视为一个int,所以x也是。


总而言之,如果操作数之一是int而另一个是char,则有两种可能的转换:

  1. 将int缩小为char(精度损失)
  2. 将字符扩展为int(不会损失精度)
  3. 为了避免无用的损失,Java将选择第二个选项。

    执行System.out.print(false ? x : 0);时,0会在编译时转换为char(因为编译器知道不会丢失精度)。


    资源:

答案 3 :(得分:0)

因为表达式false ? i : x被编译器视为返回一个整数。由于您使用char,因此'X'在ASCII中为88,因为它们是兼容的,所以它被视为整数。

就个人而言,我认为这里至少应该有一个编译器警告。

答案 4 :(得分:0)

在第二个三元组If中,参数必须是相同的类型,否则两个中的一个是隐式转换的。

在您的示例中,x从char转换为int,而'X'的ASCII代码为88.

答案 5 :(得分:0)

其他人已经回答了为什么会这样。

如果您希望打印X,请将表达式值转换回char

System.out.print((char)(false ? i : x)); // prints X

或者您也可以将i投射到char,以便表达式的类型变为char

System.out.print(false ? (char)i : x); // prints X