Java三元运算符不工作?
假设我们有一个StringBuilder和一个double。现在,我们要附加双精度。如果double可以表示为整数(例如3.0、5.0等),我希望将其添加为整数,否则添加为double 实现这一点的第一种方法是:Java三元运算符不工作?,java,stringbuilder,ternary-operator,Java,Stringbuilder,Ternary Operator,假设我们有一个StringBuilder和一个double。现在,我们要附加双精度。如果double可以表示为整数(例如3.0、5.0等),我希望将其添加为整数,否则添加为double 实现这一点的第一种方法是: 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
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());
当d
is3.0
3将被追加时,如果d
is3.5
3.5将被追加,这仍然有效
现在我想简单地用三元运算符来做这件事:
StringBuilder sb = new StringBuilder();
double d = 3.5;
sb.append(d % 1 == 0 ? (int) d : d);
System.out.println(sb.toString());
所以现在我有一个问题,每次,如果double是
3.0
或3.5
,它将作为double值添加!只有当我在理论上对true
和false
进行转换时,它才会起作用。。。但每一次,这不是我想要的。这里有什么问题?为什么三元运算符不工作?此行为记录在JLS-15.25中
如果其中一个操作数为T类型,其中T为字节、短字符或字符,而另一个操作数为int类型的常量表达式(§15.28),其值可在T类型中表示,则条件表达式的类型为T
当你写作时
(a > b) ? 'a' : 65
第二种类型转换为char
浏览JLS,它解释了其他情况下的行为(相同的方法)。在原语数上使用三元运算符时,第二个和第三个操作数会受到二进制数字提升的影响。在您的例子中,
int
被转换为double
。这是在中指定的。此行为的原因是带有三元运算符的表达式具有定义良好的类型。JLS详细描述了如何计算此类型,但粗略地说,它是冒号之前表达式类型和冒号之后表达式类型的最小上界
例如,如果
b
是boolean
,i
是int
,d
是double
,那么b的类型是什么?i:d
是double
,因为double
是int
和double
的最小上界。当您在StringBuilder
上调用append(b?i:d)
时,您将获得带有double
参数的append
版本。在您的情况下也会发生同样的情况,是否d%1==0?(int)d:d
方法StringBuilder.append()
对不同类型的参数有许多重载。使用哪种方法重载是编译时的决定。三元运算符的结果只有一种类型,在本例中为int
或double
-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,则条件表达式的类型为short
如果其中一个操作数为T类型,其中T为字节、短字符或字符,而另一个操作数为int类型的常量表达式(§15.28),其值可在T类型中表示,则条件表达式的类型为T
如果其中一个操作数为T类型,其中T为字节、短字符或字符,而另一个操作数为int类型的常量表达式,其值可在U类型中表示,U类型是对T应用取消装箱转换的结果,则条件表达式的类型为U
否则,二进制数字提升(§5.6.2)将应用于操作数类型,条件表达式的类型是第二个和第三个操作数的提升类型
这些类型将转换为相应的基本类型,称为取消装箱。
如果一个操作数是常数int(在取消装箱之前不是整数),其值可在另一种类型中表示,则该int操作数将转换为另一种类型。
否则,较小的类型将转换为下一个较大的类型,直到两个操作数具有相同的类型。转换顺序为:
字节->短->整数->长->浮点->双精度
字符->整数->长->浮点->双精度
最终,整个条件表达式将获得其第二个和第三个操作数的类型。您应该使用
DecimalFormat(“0.#”)
来去除尾随的零,而不是强制转换为int
。奇怪的是,如果我计算d%1==0?(int)d:d
(其中d=3)在eclipse中返回“3”。但随后附加了“3.0”。但这可能是日食的结果。