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. 実際のソリューションはコンパクトではありませんが、テストが 2 回繰り返されないため、実際にはより効率的です。最初のものが機能しなかった理由を理解したいだけです。
4

2 に答える 2

1

問題は操作の順序です。最初に三項演算子が評価され、次に三項演算子式の結果に連結が適用されます。代わりにこれを試してください (文字列連結式を括弧で囲みます):

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

finalAmountがさまざまなスレッド間で共有される場合は、 として宣言する必要がありますvolatile。各スレッドが常に の最新の値を読み取るようにします。これはfinalAmount、各スレッドが値をローカルにキャッシュし、スレッドによる読み取りにfinalAmountつながるためです。stale data変数を as として宣言volatileすると、各スレッドによって読み取られるデータが最新のものになります。

于 2013-02-28T17:13:35.870 に答える