根据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
?
答案 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中有三种类型的条件表达式:
由于int
和char
都可以转换为数字类型,因此根据此规则,表达式是数字条件表达式的示例:
如果第二个和第三个操作数表达式都是数值表达式,则条件表达式是数字条件表达式。
为了对条件进行分类,以下表达式是数字表达式:
- 独立形式(第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节)。
请注意,第四条规则准确描述了第二个例子;第二个操作数是int
(0
)类型的常量,第三个是char
,因此条件表达式将计算为char
。这将导致编译器使用print(char)
方法,该方法将打印y
。
但是,当您改为传入变量而不是传递常量时,您会倒入最后一条规则,即“......条件表达式的类型”是第二和第三个操作数的提升类型。“
如果您查看section §5.6.2 of the JLS,它会按如下方式描述类型提升的规则:
当运算符将二进制数字提升应用于一对操作数时,每个操作数必须表示可转换为数字类型的值,以下规则适用:
如果任何操作数属于引用类型,则进行拆箱转换(第5.1.8节)。
- 醇>
应用扩展基元转换(第5.1.2节)来转换由以下规则指定的一个或两个操作数:
如果任一操作数的类型为double,则另一个操作数转换为double。
否则,如果任一操作数的类型为float,则另一个操作数转换为float。
否则,如果任一操作数的类型为long,则另一个操作数转换为long。
否则,两个操作数都将转换为int类型。
通过遵循这些规则,表达式的类型将为int
,因此编译器将使用print(int)
方法,该方法将打印121
({{}}的ascii值1}})。
答案 2 :(得分:1)
121是 y 的ASCII代码,并且您已将 i 声明为整数,编译器也将 y 解释为int变量。因此,为 y 打印ASCII值。编写 System.out.print(false?(char)i:y)将打印 y 。