根据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);
Run Code Online (Sandbox Code Playgroud)
我期待它打印,y但它的打印121,为什么?
编辑
根据manouti的答案,编译器解释为int,但如果是这样,那么为什么我看到死代码i?
如果我这样做,System.out.print(false ? 0 : x);那么我得到了y,那么为什么在这种情况下编译器不会解释为int?
man*_*uti 10
121是字符的整数表示y.由于您i作为表达式的一部分提供,因此编译器将其解释为调用System.out.print(int)而不是System.out.print(char).
请注意,更改为System.out.print(false ? (char)i : y);打印y.
您的问题的简短答案是打印的值基于条件表达式计算的类型。
\n\n所以你的问题实际上可以归结为,为什么条件表达式的类型在不同之间有所不同
\n\nchar y = \'y\';\nint i = 0;\nSystem.out.print(false ? i : y); // prints 121\nRun Code Online (Sandbox Code Playgroud)\n\n和
\n\nchar y = \'y\';\nSystem.out.print(false ? 0 : y); // prints y\nRun Code Online (Sandbox Code Playgroud)\n\n要回答这个问题,我们需要查看Java 语言规范 的 \xc2\xa715.25 部分。
\n\nJava中的条件表达式分为三种类型:
\n\n由于 和int都可以转换为数值类型,因此该表达式是根据以下规则的数值条件表达式char的示例:
\n\n\n如果第二和第三操作数表达式都是数值表达式,则条件表达式是数值条件表达式。
\n\n为了对条件进行分类,以下表达式是数值表达式:
\n\n\n
\n- 独立形式 (\xc2\xa715.2) 的表达式,其类型可转换为数字类型 (\xc2\xa74.2、\xc2\xa75.1.8)。
\n
鉴于此,确定整个表达式类型的规则如下:
\n\n\n\n\n15.25.2。数字条件表达式
\n\n数字条件表达式是独立表达式 (\xc2\xa715.2)。
\n\n数值条件表达式的类型确定如下:
\n\n\n
\n\n- \n
如果第二个和第三个操作数具有相同的类型,则这就是条件表达式的类型。
- \n
如果第二个和第三个操作数之一是原始类型 T,而另一个操作数的类型是对 T 应用装箱转换 (\xc2\xa75.1.7) 的结果,则条件表达式的类型为 T。
- \n
如果其中一个操作数的类型为 byte 或 Byte,另一个操作数的类型为 Short 或 Short,则条件表达式的类型为 Short。
- \n
如果其中一个操作数是 T 类型,其中 T 是 byte、short 或 char,而另一个操作数是 int 类型的常量表达式 (\xc2\xa715.28),其值可以用类型 T 表示,则条件表达式为T。
- \n
如果其中一个操作数是 T 类型,其中 T 是 Byte、Short 或 Character,另一个操作数是 int 类型的常量表达式,其值可以用类型 U 表示,U 类型是对 T 应用拆箱转换的结果,则条件表达式的类型为 U。
- \n
否则,将对操作数类型应用二进制数值提升 (\xc2\xa75.6.2),并且条件表达式的类型是第二个和第三个操作数的提升类型。
请注意,二进制数字提升执行值集转换 (\xc2\xa75.1.13),并且可能执行拆箱转换 (\xc2\xa75.1.8)。
\n
请注意,第四条规则准确描述了第二个示例;第二个操作数是int( 0) 类型的常量,第三个操作数是 a char,因此条件表达式的计算结果为char。这将导致编译器使用该print(char)方法,该方法将打印y.
然而,当您传入变量而不是常量时,您会陷入最后一条规则,即“...条件表达式的类型是第二个和第三个操作数的提升类型”。
\n\n如果您查看JLS 的 \xc2\xa75.6.2 部分,它描述了类型提升的规则,如下所示:
\n\n\n\n\n当运算符将二进制数字提升应用于一对操作数时(每个操作数必须表示可转换为数字类型的值),将按顺序应用以下规则:
\n\n\n
\n- \n
如果任何操作数是引用类型,则对其进行拆箱转换(\xc2\xa75.1.8)。
- \n
加宽基元转换 (\xc2\xa75.1.2) 用于按照以下规则指定转换一个或两个操作数:
\n\n\n
- \n
如果其中一个操作数的类型为 double,则另一个操作数将转换为 double。
- \n
否则,如果任一操作数的类型为 float,则另一个将转换为 float。
- \n
否则,如果任一操作数的类型为 long,则另一个将转换为 long。
- \n
否则,两个操作数都转换为 int 类型。
通过遵循这些规则,表达式的类型将为int,因此编译器将使用该print(int)方法,该方法将打印121( 的 ascii 值y)。