Java 1.4中三元条件运算符的意外副作用

时间:2013-02-28 16:29:10

标签: java long-integer ternary-operator java1.4

我今天遇到了一个意外的错误,涉及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. 尽管工作解决方案不太紧凑,但实际上效率更高,因为测试不会重复两次。我只是想了解为什么第一个不起作用。

2 个答案:

答案 0 :(得分:1)

问题在于操作顺序。首先评估三元运算符,然后将串联应用于三元运算符表达式的结果。请尝试这样做(在字符串连接表达式周围添加括号):

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

答案 1 :(得分:1)

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