我今天遇到了一个意外的错误,涉及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,而不是""
时。但是,Number的设置是正确的。
但是,这有效:
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
,并且是该方法的局部。
免责声明 -我知道:
- 在2013年使用Java 1.4是一个异端。遗憾的是,这件事不是我说了算。
- 工作解决方案,尽管不太紧凑,但实际上效率更高,因为测试不重复两次。我只是想知道为什么第一个不行。
问题是操作顺序。首先计算三元运算符,然后将连接应用于三元运算符表达式的结果。试试这个(用圆括号括住字符串连接表达式):
product.setValue((finalAmount == 0) ? StringUtils.EMPTY : (ConversionUtil.bigDecimalToString(value) + " " + code));
如果finalAmount
被多个线程共享,那么它应该被声明为volatile
。这样每个线程总是读取finalAmount
的最新值,因为每个线程在本地缓存finalAmount
的值,从而导致线程读取stale data
。将变量声明为volatile
可确保每个线程读取的数据是最新的。