Java 输出与我期望的不同
为什么要打印X88Java 输出与我期望的不同,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
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,我已更新以向您展示更多解释和技巧;)@马修:哎呀,错了一点,但想法是对的——编辑。(如果要删除否决票,现在已修复:)