Java三元运算符输出的结果与if-else语句不同



我正在编写一个程序,该程序接受一个数字,如果该数字是整数,则删除后面的零。我正在使用三元运算符,但它没有按预期工作。但如果我把它写成if-else语句,它就会起作用。

import java.util.Scanner;
public class Main {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
double number = scanner.nextDouble();
System.out.println(((int)number == (double)number) ? (int)number : number); // Always outputs a double
if ((int)number == (double)number) { // Outputs correct result
System.out.println((int)number);
}
else {
System.out.println(number);
}
}
}

例如,如果我输入5,我会得到

5.0
5

如果我输入7.3,我会得到

7.3
7.3

因此,它似乎适用于if-else语句,但不适用于三元运算符。

在if/else语句中,根据要执行的分支调用PrintStream.println(int)PrintStream.println(double)

使用条件运算符?:您总是调用PrintStream.println(double),因为这是?:表达式的类型。当?:运算符的第二个和第三个操作数具有不同的类型时,编译器根据JLS 15.25的规则选择表达式的总体类型,并在必要时执行适当的转换。

在这种情况下,总体类型是double,所以就好像您在写:

double tmp = ((int) number == (double)number) ? (int)number : number;
System.out.println(tmp);

这种行为完全正常,是由类型解析引起的。

三元运算符本身有一个类型,它是由可能的结果推断出来的。由于一个结果具有类型(int(,另一个具有类型(double(,因此三元运算符的类型始终为double。

故事的其余部分应该很清楚。将双精度打印到控制台将始终产生小数点表示。

为了扩展提供的关于这个问题的信息:理解JLS 15.25提供的表的关键是bnp/lub操作,它代表"二进制数提升"/"最小上界";。

二进制数提升是将较小的数字类型转换为较大的数字类型,以便可以进行整数和浮点运算。这样你就可以对不同类型的数字数据进行比特级操作(比较、等式等(。如果必要,字节(8位(将升级为字符(16位(,字符也将升级为短字符(16比特(。之后,如果需要确保操作时的兼容性,shorts将转换为int(32位(。必要时,int(32位(值也会转换为long(64位(。根据需要,将长(64位(和浮点(32位(转换为双(64位的(值。

简而言之:使用BNP,较小的数据类型将转换为较大的数据类型,以确保兼容性。

最低上限债券的作用恰恰相反。如果您有一个short(16位(和一个int(32位(,但int没有存储大于16位的值,则LUB操作会将其缩小到16位。

最新更新