Ich habe zwei Möglichkeiten gefunden, um ein BigDecimal-Objekt aus einem doppelten d herauszuholen.
1. new BigDecimal(d)
2. BigDecimal.valueOf(d)
Welches wäre ein besserer Ansatz? Würde valueOf ein neues Objekt erstellen?
Was wird im Allgemeinen (nicht nur BigDecimal) empfohlen - neu oder valueOf?
Vielen Dank.
java
bigdecimal
Manish Mulani
quelle
quelle
Antworten:
Das sind zwei getrennte Fragen: "Wofür soll ich verwenden
BigDecimal
?" und "Was mache ich im Allgemeinen?"Denn
BigDecimal
: das ist etwas knifflig, weil sie nicht dasselbe machen .BigDecimal.valueOf(double)
verwendet die kanonischeString
Darstellung des übergebenendouble
Werts, um dasBigDecimal
Objekt zu instanziieren . Mit anderen Worten: Der Wert desBigDecimal
Objekts entspricht dem, was Sie dabei sehenSystem.out.println(d)
.Wenn Sie
new BigDecimal(d)
jedoch verwenden,BigDecimal
versucht der, dendouble
Wert so genau wie möglich darzustellen . Dies führt normalerweise dazu, dass viel mehr Ziffern gespeichert werden, als Sie möchten. Genau genommen ist es korrekter alsvalueOf()
, aber es ist viel weniger intuitiv.Im JavaDoc gibt es eine schöne Erklärung dafür:
In der Regel , wenn das Ergebnis das gleiche ist (also nicht im Fall
BigDecimal
, aber in den meisten anderen Fällen), dannvalueOf()
sollte bevorzugt werden: es Caching von gemeinsamen Werten tun (wie gesehen aufInteger.valueOf()
) und es kann sogar das Caching - Verhalten ändern , ohne Der Anrufer muss geändert werden.new
wird immer einen neuen Wert, wenn auch nicht notwendig (: beste Beispiel instanziiertnew Boolean(true)
vs.Boolean.valueOf(true)
).quelle
new BigDecimal()
besser alsBigDecimal.valueOf()
?new BigDecimal()
bevorzugt wird und wann ein BeispielBigDecimal.valueOf()
bevorzugt wird?new BigDecimal(1.0/30.0);
undBigDecimal.valueOf(1.0/30.0)
. Sehen Sie, welches Ergebnis tatsächlich näher am numerischen Bruch 1/30 liegt.Wenn Sie Ihre
BigDecimal
Objekte zum Speichern von Währungswerten verwenden, empfehle ich dringend, dass Sie KEINE doppelten Werte in ihre Berechnungen einbeziehen.Wie in einer anderen Antwort angegeben, sind Genauigkeitsprobleme mit doppelten Werten bekannt, die Sie erneut verfolgen werden.
Sobald Sie darüber hinweg sind, ist die Antwort auf Ihre Frage einfach. Verwenden Sie immer die Konstruktormethode mit dem String-Wert als Argument für den Konstruktor, da es keine
valueOf
Methode für gibtString
.Wenn Sie einen Beweis wünschen, versuchen Sie Folgendes:
Sie erhalten folgende Ausgabe:
Siehe auch diese verwandte Frage
quelle
Grundsätzlich macht valueOf (double val) genau das:
return new BigDecimal(Double.toString(val));
Deshalb -> ja, wird ein neues Objekt erstellt :).
Im Allgemeinen denke ich, dass es von Ihrem Codierungsstil abhängt. Ich würde valueOf und "new" nicht mischen, wenn beide das gleiche Ergebnis sind.
quelle
valueOf()
hat das intuitivere Verhalten, währendnew BigDecimal(d)
das korrektere . Probieren Sie beide aus und sehen Sie den Unterschied.new BigDecimal(1) != new BigDecimal(1)
aberBigDecimal.valueOf(1) == BigDecimal.valueOf(1)
BigDecimal
unveränderlich ist es sollte die gleiche Art und Weise behandelt werden , dass die primitiven Wrapper (Integer
,Byte
, ...) undString
behandelt werden: Objektidentität sollte keine Rolle spielen, um Ihren Code, nur der Wert sollte Materie.valueOf()
sollte generell bevorzugt werden. Beachten Sie jedoch, dassBigDecimal.valueOf(double)
kein Caching durchgeführt wird (und es sich wahrscheinlich auch nicht lohnt).