Java 输出与我期望的不同

Java 输出与我期望的不同,java,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); } 对于第一条语句System.out.print(false?x:0)编译器认为您要打印字符,因此0将被视为字符(在编译期间) 当您执行System.out.pr

为什么要打印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);
}

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

当您执行
System.out.print时(false?i:x)编译器认为您想要打印一个整数,因此它将尝试将“X”转换为一个88的整数

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

System.out.print(true ? x : i);
由于
i
不能被视为字符(需要缩小),它将打印88

这里还有一件有趣的事:

System.out.print(true  ? x : 65536);
这一次,值
65536
在编译时不能被视为字符(字符的最大值是
65535
[@See Character.max_value]),因此它将被视为int,因此x也将被视为int


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

  • int缩小为char(精度损失)
  • 字符被加宽为整数(不损失精度)
  • 为了避免无用的损失,Java将选择第二个选项

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


    资源:


      • 因为表达式
        为false?编译器将i:x
        视为返回一个整数。因为您使用的是
        char
        字符,所以“X”在ASCII中是88,并且它被视为一个整数,因为它们是兼容的


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

        在第一个
        print
        语句中,条件表达式的类型是char(即“X”),因为这部分(关于条件表达式的类型)适用于:

        如果其中一个操作数为T类型,其中T为字节、短字符或字符,而另一个操作数为int类型的常量表达式,其值可在T类型中表示,则条件表达式的类型为T

        所以第一条语句打印“X”

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

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


        二进制数字提升将字符“X”转换为int(88),第二条语句打印“88”-因此第二个三元中的“X88”的整体结果。如果参数必须是相同的类型,则这两个参数中的一个将隐式转换


        在您的示例中,x从char转换为int,“x”的ASCII码为88

        其他人已经回答了为什么会发生这种情况

        如果要打印
        X
        ,请将表达式值转换回
        char
        ,如下所示:

        System.out.print((char)(false ? i : x)); // prints X
        
        System.out.print(false ? (char)i : x); // prints X
        
        或者您也可以将
        i
        强制转换为
        char
        ,使表达式的类型变为
        char

        System.out.print((char)(false ? i : x)); // prints X
        
        System.out.print(false ? (char)i : x); // prints X
        
        这在JLS的一部分中进行了解释

        否则,如果第二个和第三个 操作数的类型是 可转换(§5.1.8)为数字类型, 然后有几个案例:

        这适用于这两个语句,因为char和int都是数值类型,因此5.1.8非常适用。因此,我们来看看下面的规则(节选):

        [……]

        • 如果其中一个操作数的类型为T,其中T为字节、短或 字符,另一个操作数是 int类型的常量表达式 值可在类型T中表示,则 条件表达式的类型 是T
        这适用于第一个,因为0是int类型的常量表达式。T是,
        char
        ,这就是它打印为X的原因

        [……]

        • 否则,二进制数字提升()将应用于 操作数类型,以及 条件表达式是提升的 第二个和第三个操作数的类型。 请注意,二进制数字升级 执行拆箱转换(§5.1.8) 和值集转换(§5.1.13)
        这适用于第二种情况,因为其他情况都不适用。:)相关规则如下所示:

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


        “X”的Unicode代码点是88。

        System.out.print(true?X:0);为什么它不打印成整数呢statement@user457708:我已经用JLS引号编辑了我的答案,以回答这个问题。@user457708,我已更新以向您展示更多解释和技巧;)@马修:哎呀,错了一点,但想法是对的——编辑。(如果要删除否决票,现在已修复:)