【问题标题】:Java: Conditional Operator differs from if/elseJava:条件运算符不同于 if/else
【发布时间】:2014-08-11 14:10:47
【问题描述】:

为什么在下面的例子中条件运算符返回 2.0 而 if/else 块返回 2?我有点困惑,因为这两个块应该相等:

如果/否则:

double value = 2.0;
Object result;

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

条件运算符:

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

但是,命令

System.out.println(result);

打印 2.0 或 2

感谢您的帮助!

【问题讨论】:

  • 您依靠自动装箱将整数或双精度数转换为对象。如果您想确保获得正确的对象,请自己使用new Integer((int)value)new Double(value) 制作它们。
  • 谢谢,但是 new Integer(value) 和 (Integer)(int) value 都不会使条件运算符返回 2 但总是 2.0

标签: java if-statement operator-keyword


【解决方案1】:

在这两种情况下都采用相同的分支。您可以通过对不同分支使用非常不同的答案来验证这一点:

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

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

在这两种情况下,您都会得到 200 或 200.0。

验证这一点的另一种选择是通过使其保持不变来移除条件:

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

result = condition ? ...;

但是,不同的是,使用条件运算符时,条件表达式的类型是double——第二个操作数的类型是int(由于强制转换),第三个操作数的类型是double。条件运算符只能有 one 类型,因此它遵循 JLS 中的规则并选择double(因为int 可以隐式转换为double,反之则不行)。然后将 double 作为分配给 result(类型为 Object)的一部分装箱。所以result 的值最终是对Double 的引用,并打印为 2.0。

使用第一种方法,结果是 Integer,因为您将 int 直接分配给 result,它只是自动装箱。

您可以通过将任一操作数转换为Object 来使条件运算符的行为方式相同。例如:

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

现在条件运算符本身的类型是Object,作为评估条件运算符的一部分,int 被装箱到Integer

【讨论】:

  • 耶稣 :) 这真是一个完美的解释。非常感谢您的帮助和解释。
【解决方案2】:

条件运算符?: 的两个可能值的类型应该相同。如果一个值的类型可以转换为另一个值,则值会有一点不同的空间。在这种情况下,即使您将value 显式转换为int,另一个值也是double,因此会发生二进制数字提升,并且int 会重新提升为double。这就是打印2.0 的原因。

JLS 的第 15.25 节介绍了 ?: 运算符,Section 15.25.2 涵盖了此运算符的数值。

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

  • 如果第二个和第三个操作数的类型相同,那么就是条件表达式的类型。

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

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

  • 如果其中一个操作数是 T 类型,其中 T 是 byte、short 或 char,而另一个操作数是 int 类型的常量表达式(第 15.28 节),其值可在类型 T 中表示,则条件表达式是T。

  • 如果其中一个操作数是 T 类型,其中 T 是 Byte、Short 或 Character,而另一个操作数是 int 类型的常量表达式,其值可在 U 类型中表示,这是应用拆箱转换的结果到T,则条件表达式的类型为U。

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

(强调我的)

【讨论】:

  • 我认为“应该是一样的”正在拉伸它。当它们不相同时会发生什么,这是很明确的,而且在大多数情况下,它是相当清楚的。
猜你喜欢
  • 2019-10-20
  • 2023-03-03
  • 1970-01-01
  • 2016-02-20
  • 2011-06-04
  • 1970-01-01
  • 2022-12-06
  • 1970-01-01
  • 2014-01-29
相关资源
最近更新 更多