BigDecimalオブジェクトをdouble dから取得する方法は2つありました。
1. new BigDecimal(d)
2. BigDecimal.valueOf(d)
どちらがより良いアプローチでしょうか?valueOfは新しいオブジェクトを作成しますか?
一般に(BigDecimalだけでなく)、何が推奨されますか-newまたはvalueOf?
ありがとう。
BigDecimalオブジェクトをdouble dから取得する方法は2つありました。
1. new BigDecimal(d)
2. BigDecimal.valueOf(d)
どちらがより良いアプローチでしょうか?valueOfは新しいオブジェクトを作成しますか?
一般に(BigDecimalだけでなく)、何が推奨されますか-newまたはvalueOf?
ありがとう。
回答:
これらは2つの異なる質問です。「何に使用すればよいBigDecimal
ですか?」そして「私は一般的に何をしますか?」
のためBigDecimal
:同じことをしないため、これは少しトリッキーです。渡された値の正規表現BigDecimal.valueOf(double)
を使用して、オブジェクトをインスタンス化します。つまり、オブジェクトの値は、実行時に表示されるものになります。String
double
BigDecimal
BigDecimal
System.out.println(d)
new BigDecimal(d)
ただし、を使用BigDecimal
すると、はdouble
値をできるだけ正確に表現しようとします。これにより、通常、必要以上に多くの桁が保存されます。厳密に言うと、はより正確ですがvalueOf()
、直感的ではありません。
これについてJavaDocに説明があります。
このコンストラクターの結果は、いくらか予測できない場合があります。
new BigDecimal(0.1)
Java で書くと、BigDecimal
正確に0.1(スケールなしの値1、スケール1)が作成されると想定するかもしれませんが、実際には0.1000000000000000055511151231257827021181583404541015625に等しいと考えられます。これは、0.1をaとして正確に表すことはできないためですdouble
(つまり、有限の長さの2進小数として)。したがって、コンストラクターに渡される値は、外観にもかかわらず、正確に0.1とは異なります。
一般に、結果が同じである場合(つまり、の場合ではないが、BigDecimal
他のほとんどの場合)、valueOf()
推奨されます。これにより、(に示されているようにInteger.valueOf()
)一般的な値のキャッシュを実行でき、キャッシュの動作を変更することもできます。発信者を変更する必要があります。new
ます常に、たとえ不要(:最良の例新しい値をインスタンスnew Boolean(true)
対をBoolean.valueOf(true)
)。
new BigDecimal()
よりも良いですかBigDecimal.valueOf()
?
new BigDecimal()
好ましいであろうとする場合の例BigDecimal.valueOf()
好ましいであろうか?
new BigDecimal(1.0/30.0);
とBigDecimal.valueOf(1.0/30.0)
。実際に数値の1/30に近い結果を確認してください。
BigDecimal
オブジェクトを使用して通貨値を格納している場合は、計算にdouble値を含めないことを強くお勧めします。
別の回答で述べたように、double値には既知の精度の問題があり、これらは大きな時間を悩ませます。
あなたがそれを乗り越えると、あなたの質問への答えは簡単です。にはvalueOf
メソッドがないため、コンストラクタの引数として常にString値を使用してコンストラクタメソッドを使用しString
ます。
証明が必要な場合は、以下を試してください。
BigDecimal bd1 = new BigDecimal(0.01);
BigDecimal bd2 = new BigDecimal("0.01");
System.out.println("bd1 = " + bd1);
System.out.println("bd2 = " + bd2);
次の出力が得られます。
bd1 = 0.01000000000000000020816681711721685132943093776702880859375
bd2 = 0.01
この関連質問も参照してください
基本的にvalueOf(double val)はこれを行うだけです:
return new BigDecimal(Double.toString(val));
したがって、->はい、新しいオブジェクトが作成されます:)。
一般的には、コーディングスタイルに依存すると思います。valueOfと "new"の両方が同じ結果である場合は、混合しません。
valueOf()
より直感的な振る舞いnew BigDecimal(d)
があり、より正確な振る舞いがあります。両方を試して、違いを確認してください。
new BigDecimal(1) != new BigDecimal(1)
、しかしBigDecimal.valueOf(1) == BigDecimal.valueOf(1)
BigDecimal
、それはプリミティブラッパー(のと同じように扱われるべき不変であるInteger
、Byte
、...)とはString
、オブジェクトIDは:扱われるのは問題ないはずあなたのコードに、唯一の値が重要でなければなりません。
valueOf()
が一般的に好まれるべきだと私が言った理由です。しかし、これBigDecimal.valueOf(double)
はキャッシングを行わないことに注意してください(そして、おそらくそれも価値がありません)。