1

我今天遇到了一个意外的错误,涉及 Java 1.4 中的三元条件运算符。

以下代码没有产生预期的结果:

product.setValue((finalAmount == 0) ? StringUtils.EMPTY : ConversionUtil.bigDecimalToString(value) + " " + code);
product.setNumber((finalAmount == 0) ? StringUtils.EMPTY : ConversionUtil.formatLongToAmountString(new Long(finalAmount)));

finalAmount == 0,Value设置为 BlahBlahStuff,而不是""。但是,数字设置正确。

但是,这有效:

if (finalAmount == 0) {
    product.setValue(StringUtils.EMPTY);
    product.setNumber(StringUtils.EMPTY);
}
else {
    product.setValue(ConversionUtil.bigDecimalToString(value) + " " + code);
    product.setNumber(ConversionUtil.formatLongToAmountString(new Long(finalAmount)));
}

为什么测试会在一条线上工作而不是另一条线? finalAmount是一个原始的long,并且是这个方法的本地。

免责声明- 我知道:

  1. 在 2013 年使用 Java 1.4 是异端邪说。可悲的是,我对此并不做主。
  2. 工作解决方案尽管不那么紧凑,但实际上效率更高,因为测试不会重复两次。我只是想了解为什么第一个不起作用。
4

2 回答 2

1

The problem is order of operations. The ternary operator is evaluated first, then the concatenation is applied to the result of the ternary operator expression. Try this instead (put parentheses around the string concatenation expressions):

product.setValue((finalAmount == 0) ? StringUtils.EMPTY : (ConversionUtil.bigDecimalToString(value) + " " + code));
于 2013-02-28T16:33:29.123 回答
1

如果finalAmount是在各个线程之间共享的,那么它应该被声明为volatile。这样每个 Thread 总是读取 的最新值finalAmount,因为每个线程都在本地缓存finalAmount导致stale dataThreads 读取的值。将变量声明为volatile确保每个线程读取的数据都是最新的。

于 2013-02-28T17:13:35.870 回答