简体   繁体   English

Java:条件运算符与if / else不同

[英]Java: Conditional Operator differs from if/else

why does the conditional operator return 2.0 and the if/else block returns 2 in the following example? 为什么条件运算符返回2.0并且if / else块在以下示例中返回2? I am kind of confused because these two blocks should be equal: 我有点困惑,因为这两个块应该相等:

IF/ELSE: 如果别的:

double value = 2.0;
Object result;

if (value == Math.floor(value)) {
    result = ((int) value);
} else {
    result = value;
}

CONDITIONAL OPERATOR: 有条件的操作员:

double value = 2.0;
Object result;
result = value == Math.floor(value) ? ((int) value) : value;

However, the command 但是,命令

System.out.println(result);

prints either 2.0 or 2 打印2.0或2

Thanks for your help! 谢谢你的帮助!

The same branch is being taken in both cases. 两种情况都采用相同的分支。 You can verify that by using very different answers for the different branches: 您可以通过对不同分支使用非常不同的答案来验证:

if (value == Math.floor(value)) {
    result = ((int) value * 100);
} else {
    result = value;
}

and

result = value == Math.floor(value) ? ((int) value * 100) : value;

In both cases, you'll get 200 or 200.0. 在这两种情况下,您将获得200或200.0。

Another option to validate that would just be to remove the conditionality by making it constant: 另一个验证方法是通过使条件不变来删除条件:

boolean condition = true;
if (condition) { 
    ...
}

and

result = condition ? ...;

However, the difference is that with the conditional operator, the type of the conditional expression is double - the type of the second operand is int (due to the cast), and the type of the third operand is double . 但是,区别在于条件运算符,条件表达式的类型是double - 第二个操作数的类型是int (由于强制转换),第三个操作数的类型是double The conditional operator can only have one type, so it follows the rules in the JLS and picks double (as int is implicitly convertible to double but not vice versa). 条件运算符只能有一个类型,因此它遵循JLS中的规则并选择double (因为int可以隐式转换为double但反之亦然)。 That double is then boxed as part of the assignment to result (which is of type Object ). 然后将该double作为result赋值的一部分(其类型为Object )。 So the value of result ends up being a reference to a Double , and printed out as 2.0. 因此, result的值最终成为对Double的引用,并打印为2.0。

With the first approach, the result is an Integer instead, because you're assigning the int directly to result , and it's just getting autoboxed. 使用第一种方法,结果是Integer ,因为您将int直接分配给result ,并且它只是自动进行了对比。

You can make the conditional operator behave the same way by casting either operand to Object . 您可以通过将操作数强制转换为Object来使条件运算符的行为方式相同。 For example: 例如:

result = value == Math.floor(value) ? ((int) value) : (Object) value;

Now the type of the conditional operator itself is Object , the int is boxed to Integer as part of evaluating the conditional operator. 现在条件运算符本身的类型是Objectint作为评估条件运算符的一部分被装箱到Integer

The types of the two possible values for the conditional operator ?: should be the same. 条件运算符的两个可能值的类型?:应该是相同的。 There is a little room for the values to be different, if the type of one value can be converted to the other. 如果一个值的类型可以转换为另一个值,则值有一点不同的空间。 In this case, even when you explicitly cast value to int , the other value is a double , so binary numeric promotion occurs, and the int is re-promoted to double . 在这种情况下,即使您将value显式转换为int ,另一个值也是double ,因此会发生二进制数字提升,并将int重新提升为double That's why 2.0 is printed. 这就是打印2.0的原因。

Section 15.25 of the JLS covers the ?: operator, and Section 15.25.2 covers numeric values for this operator. JLS的第15.25节涵盖了?:运算符, 第15.25.2节涵盖了该运算符的数值。

The type of a numeric conditional expression is determined as follows: 数字条件表达式的类型确定如下:

  • If the second and third operands have the same type, then that is the type of the conditional expression. 如果第二个和第三个操作数具有相同的类型,那么这就是条件表达式的类型。

  • If one of the second and third operands is of primitive type T, and the type of the other is the result of applying boxing conversion (§5.1.7) to T, then the type of the conditional expression is T. 如果第二个和第三个操作数之一是原始类型T,而另一个操作数的类型是对T应用装箱转换(第5.1.7节)的结果,那么条件表达式的类型是T.

  • If one of the operands is of type byte or Byte and the other is of type short or Short, then the type of the conditional expression is short. 如果其中一个操作数的类型为字节或字节,另一个操作数的类型为short或Short,则条件表达式的类型为short。

  • If one of the operands is of type T where T is byte, short, or char, and the other operand is a constant expression (§15.28) of type int whose value is representable in type T, then the type of the conditional expression is T. 如果其中一个操作数是T类型,其中T是byte,short或char,另一个操作数是int类型的常量表达式(第15.28节),其值可以在类型T中表示,那么条件表达式的类型是T.

  • If one of the operands is of type T, where T is Byte, Short, or Character, and the other operand is a constant expression of type int whose value is representable in the type U which is the result of applying unboxing conversion to T, then the type of the conditional expression is U. 如果其中一个操作数是T类型,其中T是Byte,Short或Character,另一个操作数是int类型的常量表达式,其值可以在类型U中表示,这是将拆箱转换应用于T的结果,那么条件表达式的类型是U.

  • Otherwise, binary numeric promotion (§5.6.2) is applied to the operand types, and the type of the conditional expression is the promoted type of the second and third operands. 否则,二进制数字提升(第5.6.2节)将应用于操作数类型,条件表达式的类型是第二个和第三个操作数的提升类型。

(emphasis mine) (强调我的)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM