Java - 三元运算符奇怪的行为

时间:2016-03-27 08:35:39

标签: java double ternary-operator

我试图从$(document).on('click','.cancella_immagine', function () { $(this).parent().prev('.thumb-image').hide(); }); 移除fractional部分,以防它全部使用:

double

遇到以下我不明白的行为:

(d % 1) == 0 ? d.intValue() : d

正如您在第三行看到的那样,即使符合条件public static void main(String[] args) { Double d = 5D; System.out.println((d % 1) == 0); // true System.out.println((d % 1) == 0 ? d.intValue() : "not whole"); // 5 System.out.println((d % 1) == 0 ? d.intValue() : d); // 5.0 } ,运营商也会选择else值 - 5.0

这里发生了什么?

4 个答案:

答案 0 :(得分:35)

三元条件运算符的返回类型必须是第2和第3个操作数都可以分配给它。

因此,在第二种情况下,运算符的返回类型为Object(因为d.intValue()"not whole"都必须可分配给它),而在第三种情况下,它是{ {1}}(因为Doubled.intValue()都必须可分配给它)。

在打印d时打印运行时类型为Object的{​​{1}}会向您Integer提供5

答案 1 :(得分:11)

表达式a ? b : c的类型始终与c或最近的bc的共同父项相同。

System.out.println((d % 1) == 0 ? d.intValue() : "not whole");  // Comparable a parent of Integer and String
System.out.println((d % 1) == 0 ? d.intValue() : d);            // Double is a widened int

BTW d % 1只检查它是不是整体,而不是它足够小以适应int值。更安全的检查是在投射到intlong

时查看值是否相同
double d = 5.0;
if ((long) d == d)
    System.out.println((long) d);
else
    System.out.println(d);

或者您可以阻止它使用

long扩展回双倍
double d = 5.0;
System.out.println((long) d == d ? Long.toString((long) d) : Double.toString(d));

答案 2 :(得分:3)

选择正确。然后它将它包装成双倍。这些是3个要点:

  1. 如果第二个和第三个操作数具有相同的类型,那么这是条件表达式的类型。换句话说,你可以通过避开混合型计算来避免整个混乱。

  2. 如果其中一个操作数是T类型,其中T是byte,short或char,另一个操作数是int类型的常量表达式,其值可以在类型T中表示,条件表达式的类型是吨。

  3. 否则,二进制数字提升将应用于操作数类型,条件表达式的类型是第二个和第三个操作数的提升类型。

答案 3 :(得分:1)

在您的情况下,ternery运算符的第二个和第三个参数是“int”和“Double”类型。 Java必须将这些值转换为相同的类型,以便可以从三元运算符返回它们。执行此操作的规则在Java语言规范中给出。 https://docs.oracle.com/javase/specs/jls/se7/html/jls-15.html#jls-15.25

在这种情况下,这些规则会导致两个参数都转换为“double”类型(“Double”是未装箱的,int是值转换的。)

修复是将参数转换为三元运算符,使它们属于同一类型(下面可能有更多括号,而不是严格需要的,我对java运算符优先级规则有点生疏)。

System.out.println((d % 1) == 0 ? ((Number)(d.intValue())) : (Number)d);