Java三元运算符不工作?

问题描述:

我们假设我们有一个StringBuilder和一个double。现在想要追加双。如果double可以表示为Integer(例如3.0,5.0等),我想将它添加为Integer,否则为double。Java三元运算符不工作?

第一种方法来实现,这是:

StringBuilder sb = new StringBuilder(); 
double d = 3.5; 

if (d % 1 == 0) sb.append((int) d); 
else sb.append(d); 

System.out.println(sb.toString()); 

这工作还是不错的,当d3.0 3将被追加,如果d3.5 3.5将被追加。

现在我想与三元运营商短期内做到这一点:

StringBuilder sb = new StringBuilder(); 
double d = 3.5; 

sb.append(d % 1 == 0 ? (int) d : d); 

System.out.println(sb.toString()); 

所以现在我有一个问题,每一次,如果双是3.03.5它将被添加作为双重价值!只有当我理论上投在truefalse它的作品......但每一次,这不是我想要的。这里有什么问题?为什么三元操作员不工作?

+0

您应该使用'DecimalFormat(“0。#”)'来摆脱尾部零,而不是转换为'int'。 –

此行为的原因是具有三元运算符的表达式具有明确定义的类型。 JLS详细描述了如何评估这种类型,但粗略地说,它是冒号前的表达式类型和冒号后的表达式类型的最小上限。

例如,如果bbooleaniintddouble,那么b ? i : d类型是double,因为double是最小上界的intdouble。当您在StringBuilder上拨打append(b ? i : d)时,将获得版本appenddouble参数。同样的事情发生在你的情况下,d % 1 == 0 ? (int) d : d

此行为记录在JLS-15.25中。 Conditional Operator ? : :

如果操作数中的一个是类型T,其中T是字节,短,或炭的,而另一个操作数是int类型的常量表达式(§15.28),其值是在类型T表示的,然后条件表达式的类型为T

当编写

(a > b) ? 'a' : 65 

所述第二类型被转换为炭。

通过JLS,它解释了其他情况下的行为(同样的方法)。

+0

奇怪的是,如果我评估'd%1 == 0? (int)d:d'(其中d = 3)返回“3”。但随后附加“3.0”。但这可能是Eclipse的一件事。 –

在基本数字上使用三元运算符时,第二个和第三个操作数受二进制数字提升的影响。在你的情况下,int被铸造为double。这在JLS #15.25中指定。

方法StringBuilder.append()对于不同类型的参数有许多过载。使用哪种方法重载是编译时决定。在这种情况下,三元运算符的结果只有一种类型,即intdouble - double

if语句的情况下,编译器根据分支使用正确的append()方法过载。

我认为编译器认为sb.append(d % 1 == 0 ? (int) d : d)sb.append(double),否则sb.append((int) d)sb.append(int)

数值条件表达式是独立表达式(§15.2)。

如果第二和第三个操作数具有相同的类型,则认为是条件表达式的类型:

类型数值条件表达式如下确定。

如果第二个和第三个操作数中的一个是原始类型T,而另一个的类型是对T应用装箱转换(第5.1.7节)的结果,则条件表达式的类型为T.

如果其中一个操作数的类型为byte或Byte,另一个的类型为short或Short,则条件表达式的类型很短。

如果其中一个操作数的类型是T,其中T是字节,短或char,另一个操作数是类型为int的常量表达式(第15.28节),其值可用T类型表示,则类型条件表达式是T.

如果其中一个操作数是T类型,其中T是Byte,Short或Character,另一个操作数是类型为int的常量表达式,其值可以在U类型中表示是将拆箱转换应用到T的结果,那么条件表达式的类型为U.

否则,对操作数类型应用二进制数字提升(第5.6.2节),并且条件表达式的类型是第二个和第三个操作数的提升类型。

这些类型被转换为它们相应的基元,这就是所谓的拆箱。 如果一个操作数是一个常量int(在拆箱前不是整数),其值可以在另一个类型中表示,则该int操作数将转换为另一个类型。 否则,较小的类型转换为下一个较大的类型,直到两个操作数具有相同的类型。转换命令是:

字节 - >短 - > INT - >长 - >浮 - >双

炭 - > INT - >长 - >浮 - >双

最终整个条件表达式获取其第二个和第三个操作数的类型。