Ich verstehe, dass BigDecimal als Best Practice für die Darstellung von Geldwerten in Java empfohlen wird. Was benutzt du? Gibt es eine bessere Bibliothek, die Sie lieber verwenden?
Ich verstehe, dass BigDecimal als Best Practice für die Darstellung von Geldwerten in Java empfohlen wird. Was benutzt du? Gibt es eine bessere Bibliothek, die Sie lieber verwenden?
Antworten:
BigDecimal
den ganzen Weg. Ich habe von einigen Leuten gehört, die ihre eigenen Cash
oder Money
Klassen erstellen , die einen Barwert mit der Währung kapseln, aber unter der Haut ist es immer noch eine BigDecimal
, wahrscheinlich mit BigDecimal.ROUND_HALF_EVEN
Rundung.
Bearbeiten: Wie Don in seiner Antwort erwähnt , gibt es Open-Source-Projekte wie timeandmoney , und obwohl ich sie dafür begrüße, dass sie versuchen, Entwickler daran zu hindern, das Rad neu zu erfinden, habe ich einfach nicht genug Vertrauen in eine Pre-Alpha-Bibliothek, um sie zu verwenden es in einer Produktionsumgebung. Übrigens, wenn Sie unter der Haube graben um, sehen Sie sie verwenden BigDecimal
zu .
Es kann für Leute, die von Suchmaschinen hierher kommen, nützlich sein, etwas über JodaMoney zu erfahren: http://www.joda.org/joda-money/ .
BigDecimal
unter der Haube ist!
Ich drücke hier nicht meine Meinung aus, aber es gibt ziemlich gute Argumente gegen BigDecimal, die wahrscheinlich jemand wegwerfen sollte:
http://lemnik.wordpress.com/2011/03/25/bigdecimal-and-your-money/
Eine praktische Bibliothek, auf die ich früher gestoßen bin, ist die Joda-Money- Bibliothek. Eine seiner Implementierungen basiert in der Tat auf BigDecimal. Es basiert auf der ISO-4217- Spezifikation für Währungen und kann eine benutzerdefinierte Währungsliste (geladen über CVS) unterstützen.
Diese Bibliothek verfügt über eine kleine Anzahl von Dateien, die bei Bedarf schnell durchsucht werden können. Joda-Money wird unter der Apache 2.0-Lizenz veröffentlicht.
Wenn Sie nur Dollar und Cent verwenden, würde ich eine lange (um 2 Dezimalstellen versetzt) verwenden. Wenn Sie mehr Details benötigen, ist möglicherweise eine große Dezimalstelle der richtige Weg.
In beiden Fällen würde ich die Klasse wahrscheinlich erweitern, um eine .toString () zu haben, die das richtige Format verwendet, und um andere Methoden zu platzieren, die möglicherweise auftauchen (Für eine lange Zeit wird das Multiplizieren und Teilen schief gehen, wenn die Dezimalstelle nicht stimmt nicht angepasst)
Wenn Sie Ihre eigene Klasse und Schnittstelle definieren, können Sie die Implementierung nach Belieben ersetzen.
BigDecimal
oder eine andere Festpunktdarstellung ist das, was im Allgemeinen für Geld benötigt wird.
Gleitkomma ( Double
, Float
) -Darstellungen und -Berechnungen sind ungenau und führen zu fehlerhaften Ergebnissen.
Man muss so vorsichtig sein, wenn man mit Zeit und Geld umgeht.
Wenn Sie mit Geld arbeiten, hoffe ich, dass jeder wissen sollte, niemals einen Float oder ein Double zu verwenden.
Bei BigDecimal bin ich mir jedoch nicht sicher.
In den meisten Fällen geht es Ihnen gut, wenn Sie nur die Cent in einem Int oder Long verfolgen. Auf diese Weise können Sie niemals mit einer Dezimalstelle umgehen.
Sie zeigen Dollars nur an, wenn Sie sie drucken. Arbeiten Sie immer mit internen Cent mit ganzen Zahlen. Dies kann schwierig sein, wenn Sie sich teilen oder Math.abs () verwenden müssen.
Möglicherweise ist Ihnen jedoch ein halber Cent oder sogar ein Hundertstel Cent wichtig. Ich weiß nicht, was ein guter Weg ist, dies zu tun. Möglicherweise müssen Sie nur mit Tausendstel Cent umgehen und eine lange verwenden. Oder Sie werden gezwungen sein, BigDecimal zu verwenden
Ich würde viel mehr darüber lesen, aber jeden ignorieren, der anfängt, über die Verwendung eines Floats oder Double zur Darstellung von Geld zu sprechen. Sie bitten nur um Ärger.
Ich bin der Meinung, dass mein Rat nicht vollständig ist. Bitte geben Sie mehr darüber an. Sie haben es mit gefährlichen Typen zu tun!
Das Erstellen einer Geldklasse ist der richtige Weg. Verwenden Sie BigDecimal (oder sogar ein Int) darunter. Verwenden Sie dann die Währungsklasse, um die Rundungskonvention zu definieren.
Leider macht es Java ohne Überlastung des Operators ziemlich unangenehm, solche Grundtypen zu erstellen.
Es gibt eine bessere Bibliothek, Zeit und Geld . IMO ist es den vom JDK zur Darstellung dieser beiden Konzepte bereitgestellten Bibliotheken weit überlegen.
Auf keinen Fall BigDecimal. Es gibt so viele spezielle Regeln für Rundungen und Präsentationen, über die Sie sich Sorgen machen müssen.
Martin Fowler empfiehlt die Implementierung einer dedizierten Geldklasse zur Darstellung von Währungsbeträgen, die auch Regeln für die Währungsumrechnung implementiert.
Hey, hier ist ein sehr interessanter Artikel über BigDecimal und ein anschauliches Beispiel dafür, warum es manchmal anstelle von Doppel verwendet wird. BigDecimal Tutorial .
Sie können die DecimalFormat-Klasse verwenden, wenn Sie letztendlich einen Währungswert anzeigen. Es bietet Lokalisierungsunterstützung und ist ziemlich erweiterbar.
Ich würde BigDecimal in die Money-Klasse einkapseln, die auch eine Währung hat, genau wie jemand, der oben erwähnt wurde. Das Wichtigste ist, dass Sie extrem viele Unit-Tests durchführen, insbesondere wenn Sie mit verschiedenen Währungen arbeiten. Es ist auch eine gute Idee, wenn Sie einen praktischen Konstruktor hinzufügen, der eine Zeichenfolge verwendet, oder eine Factory-Methode, die dasselbe tut, damit Sie Ihre Tests wie folgt schreiben können:
assertEquals(Money.create("100.0 USD").add("10 GBP"),Money.create("116 USD"));
Es gibt immer Einschränkungen und Besonderheiten. Jeder, der nicht über ausreichende Erfahrung verfügt, um die im folgenden Artikel beschriebenen subtilen Probleme zu verstehen, sollte dies vor dem Umgang mit realen Finanzdaten ernsthaft überdenken:
http://lemnik.wordpress.com/2011/03/25/bigdecimal-and-your-money
BigDecimal ist kaum die einzig richtige Darstellung oder das einzige Puzzleteil. Unter bestimmten Bedingungen könnte die Verwendung einer Money-Klasse, die durch als Ganzzahl gespeicherte Cent unterstützt wird, ausreichend sein und wäre viel schneller als BigDecimal. Ja, das impliziert die Verwendung von Dollar als Währung und Grenzbeträge, aber solche Einschränkungen sind für viele Anwendungsfälle durchaus akzeptabel, und alle Währungen haben ohnehin Sonderfälle für Rundungen und Teilbezeichnungen, sodass es keine "universelle" Lösung gibt.