按照Java三元运算符expression ? statement1 : statement2
,如果expression
为true,statement1
则将执行;如果expression
为false,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
?
对于您的问题的简短答案是,所打印的值基于条件表达式求值的类型。
所以实际上您的问题归结为,为什么条件表达式的类型之间
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
要回答这个问题,我们需要看一下Java语言规范§15.25节。
Java中有三种类型的条件表达式:
由于int
和char
均可转换为数字类型,因此该表达式是根据以下规则的数字条件表达式的示例:
如果第二和第三操作数表达式均为数字表达式,则条件表达式为数字条件表达式。
为了对条件进行分类,以下表达式是数字表达式:
- 独立形式(第15.2节)的表达式,其类型可转换为数字类型(第4.2节,第5.1.8节)。
鉴于此,确定整个表达式类型的规则如下:
15.25.2。数值条件表达式
数值条件表达式是独立表达式(第15.2节)。
数字条件表达式的类型确定如下:
如果第二和第三操作数具有相同的类型,则这是条件表达式的类型。
如果第二个操作数和第三个操作数之一是原始类型T,而另一个操作数的类型是将装箱转换(第5.1.7节)应用于T的结果,则条件表达式的类型为T。
如果操作数之一是字节或字节类型,而另一个是short或Short类型,则条件表达式的类型为short。
如果其中一个操作数的类型为T,其中T为字节,short或char,而另一个操作数为int类型的常量表达式(第15.28节),其值可在类型T中表示,则条件表达式的类型为T.
如果其中一个操作数是T类型,其中T是Byte,Short或Character,而另一个操作数是int类型的常量表达式,其值可表示为U类型,这是对T应用拆箱转换的结果,那么条件表达式的类型是U。
否则,将二进制数值提升(第5.6.2节)应用于操作数类型,条件表达式的类型为第二和第三操作数的提升类型。
请注意,二进制数值提升执行值集转换(第5.1.13节),并且可能执行拆箱转换(第5.1.8节)。
注意,第四条规则准确地描述了第二个示例。第二个操作数是int
(0
)类型的常量,第三个操作数是a的常量char
,因此条件表达式的值为char
。这将导致编译器使用print(char)
方法print y
。
但是,当您改为传入变量而不是常量时,您会陷入最后一条规则,即“ ...条件表达式的类型是第二和第三操作数的提升类型”。
如果您查看JLS的§5.6.2部分,它将描述类型提升的规则,如下所示:
当运算符将二进制数字提升应用于一对操作数时,每个操作数必须表示一个可转换为数字类型的值,以下规则适用:
如果任何操作数是引用类型,则将其进行拆箱转换(第5.1.8节)。
扩展原语转换(第5.1.2节)适用于转换以下规则指定的一个或两个操作数:
如果一个操作数的类型为double,则另一个将转换为double。
否则,如果其中一个操作数的类型为float,则另一个将转换为float。
否则,如果其中一个操作数的类型为long,则另一个将转换为long。
否则,两个操作数都将转换为int类型。
遵循这些规则,表达式的类型将为int
,因此编译器将使用该print(int)
方法进行打印121
(的ascii值y
)。
本文收集自互联网,转载请注明来源。
如有侵权,请联系 [email protected] 删除。
我来说两句