- All Superinterfaces:
java.lang.Comparable<MonetaryAmount>,CurrencySupplier,NumberSupplier
public interface MonetaryAmount extends CurrencySupplier, NumberSupplier, java.lang.Comparable<MonetaryAmount>
Each instance of an amount provides additional meta-data in form of a MonetaryContext.
This context contains detailed information on the numeric capabilities, e.g. the supported
precision and maximal scale, as well as the common implementation flavor.
Also a MonetaryAmount provides a NumberValue, which allows easily to extract the
numeric value, of the amount. And finally getFactory() provides a
MonetaryAmountFactory, which allows to of instances of MonetaryAmount based
on the same numeric implementation.
This JSR additionally recommends to consider the following aspects:
- Arithmetic operations should throw an
ArithmeticException, if performing arithmetic operations between amounts exceeds the capabilities of the numeric representation type used. Any implicit truncating, that would lead to complete invalid and useless results, should be avoided. This recommendation does not affect format rounding, as required by the format numeric representation of a monetary amount. - Monetary amounts should allow numbers as argument for arithmetic operations like division and
multiplication. Adding or subtracting of amounts must only be possible by passing instances of
MonetaryAmount. - Nevertheless numeric truncation is also explicitly supported when calling
NumberValue.numberValue(Class), whereas the exact counterpart,NumberValue.numberValueExact(Class), works similar toBigDecimal.longValueExact(). - Since implementations are recommended to be immutable, an operation should never change any format state of an instance. Given an instance, all operations are required to be fully reproducible.
- Finally the result of calling
with(MonetaryOperator)must be of the same type as type on whichwithwas called. Thewithmethod also defines additional interoperability requirements that are important to enable this invariant. - To enable further interoperability a static method
from(MonetaryAmount)is recommended to be implemented on each implementation class, that allows conversion of aMonetaryAmountto a concrete instance. E.g.a classMyMoney extends MonetaryAmountwould contain the following method:public final class MyMoney implements MonetaryAmount{ ... public static MyMoney from(MonetaryAmount amount)(...) }
Implementation specification
Implementations of this interface must be- thread-safe
- final
- serializable, hereby writing the numeric value, the
MonetaryContextand a serializedCurrencyUnit.
- thread-safe
- immutable
- comparable
- must implement
equals/hashCode, hereby considering- Implementation type
- CurrencyUnit
- Numeric value.
- Version:
- 1.1
- Author:
- Anatole Tresch, Werner Keil
- See Also:
with(MonetaryOperator)
-
Method Summary
Modifier and Type Method Description MonetaryAmountabs()Returns aMonetaryAmountwhose value is the absolute value of thisMonetaryAmount, and whose scale isthis.getContext().getMaxScale().MonetaryAmountadd(MonetaryAmount augend)Returns aMonetaryAmountwhose value isthis + augend, and whose scale ismax(this.getContext().getMaxScale(), augend.getContext().getMaxScale()).MonetaryAmountdivide(double divisor)Returns aMonetaryAmountwhose value isthis / divisor, and whose preferred scale isthis.getContext().getMaxScale() - divisor.getContext().getMaxScale(); if the exact quotient cannot be represented anArithmeticExceptionis thrown.MonetaryAmountdivide(long divisor)Returns aMonetaryAmountwhose value isthis / divisor, and whose preferred scale isthis.getContext().getMaxScale() - divisor.getContext().getMaxScale(); if the exact quotient cannot be represented anArithmeticExceptionis thrown.MonetaryAmountdivide(java.lang.Number divisor)Returns aMonetaryAmountwhose value isthis / divisor, and whose preferred scale isthis.getContext().getMaxScale() - divisor.getContext().getMaxScale(); if the exact quotient cannot be represented anArithmeticExceptionis thrown.MonetaryAmount[]divideAndRemainder(double divisor)Returns a two-elementMonetaryAmountarray containing the result ofdivideToIntegralValuefollowed by the result ofremainderon the two operands.MonetaryAmount[]divideAndRemainder(long divisor)Returns a two-elementMonetaryAmountarray containing the result ofdivideToIntegralValuefollowed by the result ofremainderon the two operands.MonetaryAmount[]divideAndRemainder(java.lang.Number divisor)Returns a two-elementMonetaryAmountarray containing the result ofdivideToIntegralValuefollowed by the result ofremainderon the two operands.MonetaryAmountdivideToIntegralValue(double divisor)Returns aMonetaryAmountwhose value is the integer part of the quotientthis / divisorrounded down.MonetaryAmountdivideToIntegralValue(long divisor)Returns aMonetaryAmountwhose value is the integer part of the quotientthis / divisorrounded down.MonetaryAmountdivideToIntegralValue(java.lang.Number divisor)Returns aMonetaryAmountwhose value is the integer part of the quotientthis / divisorrounded down.MonetaryContextgetContext()Returns theMonetaryContextof thisMonetaryAmount.MonetaryAmountFactory<? extends MonetaryAmount>getFactory()Creates a newMonetaryAmountFactory, returning the same implementation type Hereby this given amount is used as a template, so reusing theCurrencyUnit, its numeric value, the algorithmic implementation as well as the currentMonetaryContext.booleanisEqualTo(MonetaryAmount amount)Compares two instances ofMonetaryAmount, hereby ignoring non significant trailing zeroes and different numeric capabilities.booleanisGreaterThan(MonetaryAmount amount)Compares two instances ofMonetaryAmount, hereby ignoring non significant trailing zeroes and different numeric capabilities.booleanisGreaterThanOrEqualTo(MonetaryAmount amount)Compares two instances ofMonetaryAmount, hereby ignoring non significant trailing zeroes and different numeric capabilities.booleanisLessThan(MonetaryAmount amount)Compares two instances ofMonetaryAmount, hereby ignoring non significant trailing zeroes and different numeric capabilities.booleanisLessThanOrEqualTo(MonetaryAmount amt)Compares two instances ofMonetaryAmount, hereby ignoring non significant trailing zeroes and different numeric capabilities.default booleanisNegative()Checks if aMonetaryAmountis negative.default booleanisNegativeOrZero()Checks if aMonetaryAmountis negative or zero.default booleanisPositive()Checks if aMonetaryAmountis positive.default booleanisPositiveOrZero()Checks if aMonetaryAmountis positive or zero.default booleanisZero()Checks if anMonetaryAmountis zero.MonetaryAmountmultiply(double multiplicand)Returns aMonetaryAmountwhose value is(this × multiplicand), and whose scale isthis.getContext().getMaxScale() + multiplicand.getContext().getMaxScale().MonetaryAmountmultiply(long multiplicand)Returns aMonetaryAmountwhose value is(this × multiplicand), and whose scale isthis.getContext().getMaxScale() + multiplicand.getContext().getMaxScale().MonetaryAmountmultiply(java.lang.Number multiplicand)Returns aMonetaryAmountwhose value is(this × multiplicand), and whose scale isthis.getContext().getMaxScale() + multiplicand.getContext().getMaxScale().MonetaryAmountnegate()Returns aMonetaryAmountwhose value is-this, and whose scale isthis.getContext().getMaxScale(), with rounding according to the context settings.MonetaryAmountplus()Returns aMonetaryAmountwhose value is+this.default <R> Rquery(MonetaryQuery<R> query)Queries this monetary amount for a value.MonetaryAmountremainder(double divisor)Returns aMonetaryAmountwhose value isthis % divisor.MonetaryAmountremainder(long divisor)Returns aMonetaryAmountwhose value isthis % divisor.MonetaryAmountremainder(java.lang.Number divisor)Returns aMonetaryAmountwhose value isthis % divisor.MonetaryAmountscaleByPowerOfTen(int power)Returns aMonetaryAmountwhose numerical value is equal to (this* 10n).intsignum()Returns the signum function of thisMonetaryAmount.MonetaryAmountstripTrailingZeros()Returns aMonetaryAmountwhich is numerically equal to this one but with any trailing zeros removed from the representation.MonetaryAmountsubtract(MonetaryAmount subtrahend)Returns aMonetaryAmountwhose value isthis - amount, and whose scale ismax(this.getContext().getMaxScale(), subtrahend.getContext().getMaxScale().default MonetaryAmountwith(MonetaryOperator operator)Returns an operated object of the same type as this object with the operation made.
-
Method Details
-
getContext
MonetaryContext getContext()Returns theMonetaryContextof thisMonetaryAmount. TheMonetaryContextprovides additional information about the numeric representation and the numeric capabilities. This information can be used by code to determine situations whereMonetaryAmountinstances must be converted to avoid implicit truncation, which can lead to invalid results.- Returns:
- the
MonetaryContextof thisMonetaryAmount, nevernull.
-
query
Queries this monetary amount for a value.This queries this amount using the specified query strategy object.
Implementations must ensure that no observable state is altered when this read-only method is invoked.
- Type Parameters:
R- the type of the result- Parameters:
query- the query to invoke, not null- Returns:
- the query result, null may be returned (defined by the query)
-
with
Returns an operated object of the same type as this object with the operation made. Hereby returning an instance of the same type is very important to prevent uncontrolled mixup of implementations. Switching between implementations is still easily possible, e.g. by using accordingMonetaryAmountFactoryinstances:// converting from Money to MyMoney Money m = ...; MonetartyAmountFactory<MyMoney> f = Monetary.queryAmountFactory(MyMoney.class); MyMoney myMoney = f.setAmount(m).of();This converts this monetary amount according to the rules of the specified operator. A typical operator will change the amount and leave the currency unchanged. A more complex operator might also change the currency.
Some example code indicating how and why this method is used:
MonetaryAmount money = money.with(amountMultipliedBy(2)); money = money.with(amountRoundedToNearestWholeUnit());Hereby also the method signature on the implementation type must return the concrete type, to enable a fluent API, e.g.
public final class MyMoney implements MonetaryAmount{ ... public MyMoney with(MonetaryOperator operator){ ... } ... }- Parameters:
operator- the operator to use, not null- Returns:
- an object of the same type with the specified conversion made, not null
-
getFactory
MonetaryAmountFactory<? extends MonetaryAmount> getFactory()Creates a newMonetaryAmountFactory, returning the same implementation type Hereby this given amount is used as a template, so reusing theCurrencyUnit, its numeric value, the algorithmic implementation as well as the currentMonetaryContext.This method is used for creating a new amount result after having done calculations that are not directly mappable to the default monetary arithmetics, e.g. currency conversion.
- Returns:
- the new
MonetaryAmountFactorywith the givenMonetaryAmountas its default values.
-
isGreaterThan
Compares two instances ofMonetaryAmount, hereby ignoring non significant trailing zeroes and different numeric capabilities.- Parameters:
amount- theMonetaryAmountto be compared with this instance.- Returns:
trueifamount > this.- Throws:
MonetaryException- if the amount's currency is not equal to the currency of this instance.
-
isGreaterThanOrEqualTo
Compares two instances ofMonetaryAmount, hereby ignoring non significant trailing zeroes and different numeric capabilities.- Parameters:
amount- theMonetaryAmountto be compared with this instance.- Returns:
trueifamount >= this.- Throws:
MonetaryException- if the amount's currency is not equal to the currency of this instance.
-
isLessThan
Compares two instances ofMonetaryAmount, hereby ignoring non significant trailing zeroes and different numeric capabilities.- Parameters:
amount- theMonetaryAmountto be compared with this instance.- Returns:
trueifamount < this.- Throws:
MonetaryException- if the amount's currency is not equal to the currency of this instance.
-
isLessThanOrEqualTo
Compares two instances ofMonetaryAmount, hereby ignoring non significant trailing zeroes and different numeric capabilities.- Parameters:
amt- theMonetaryAmountto be compared with this instance.- Returns:
trueifamount <= this.- Throws:
MonetaryException- if the amount's currency is not equal to the currency of this instance.
-
isEqualTo
Compares two instances ofMonetaryAmount, hereby ignoring non significant trailing zeroes and different numeric capabilities.- Parameters:
amount- theMonetaryAmountto be compared with this instance.- Returns:
trueifamount == this.- Throws:
MonetaryException- if the amount's currency is not equal to the currency of this instance.
-
isNegative
default boolean isNegative()Checks if aMonetaryAmountis negative.- Returns:
trueifsignum()< 0.
-
isNegativeOrZero
default boolean isNegativeOrZero()Checks if aMonetaryAmountis negative or zero.- Returns:
trueifsignum()<= 0.
-
isPositive
default boolean isPositive()Checks if aMonetaryAmountis positive.- Returns:
trueifsignum()> 0.
-
isPositiveOrZero
default boolean isPositiveOrZero()Checks if aMonetaryAmountis positive or zero.- Returns:
trueifsignum()>= 0.
-
isZero
default boolean isZero()Checks if anMonetaryAmountis zero.- Returns:
trueifsignum()== 0.
-
signum
int signum()Returns the signum function of thisMonetaryAmount.- Returns:
- -1, 0, or 1 as the value of this
MonetaryAmountis negative, zero, or positive.
-
add
Returns aMonetaryAmountwhose value isthis + augend, and whose scale ismax(this.getContext().getMaxScale(), augend.getContext().getMaxScale()).- Parameters:
augend- value to be added to thisMonetaryAmount.- Returns:
this + augend- Throws:
java.lang.ArithmeticException- if the result exceeds the numeric capabilities of this implementation class, i.e. theMonetaryContextcannot be adapted as required.
-
subtract
Returns aMonetaryAmountwhose value isthis - amount, and whose scale ismax(this.getContext().getMaxScale(), subtrahend.getContext().getMaxScale().- Parameters:
subtrahend- value to be subtracted from thisMonetaryAmount.- Returns:
this - subtrahend- Throws:
java.lang.ArithmeticException- if the result exceeds the numeric capabilities of this implementation class, i.e. theMonetaryContextcannot be adapted as required.
-
multiply
Returns aMonetaryAmountwhose value is(this × multiplicand), and whose scale isthis.getContext().getMaxScale() + multiplicand.getContext().getMaxScale().- Parameters:
multiplicand- value to be multiplied by thisMonetaryAmount.- Returns:
this * multiplicand- Throws:
java.lang.ArithmeticException- if the result exceeds the numeric capabilities of this implementation class, i.e. theMonetaryContextcannot be adapted as required.
-
multiply
Returns aMonetaryAmountwhose value is(this × multiplicand), and whose scale isthis.getContext().getMaxScale() + multiplicand.getContext().getMaxScale(). By default the input value's scale will be rounded to accommodate the format capabilities, and noArithmeticExceptionis thrown if the input number's scale exceeds the capabilities.- Parameters:
multiplicand- value to be multiplied by thisMonetaryAmount. If the multiplicand's scale exceeds the capabilities of the implementation, it may be rounded implicitly.- Returns:
this * multiplicand- Throws:
java.lang.ArithmeticException- if the result exceeds the numeric capabilities of this implementation class, i.e. theMonetaryContextcannot be adapted as required.
-
multiply
Returns aMonetaryAmountwhose value is(this × multiplicand), and whose scale isthis.getContext().getMaxScale() + multiplicand.getContext().getMaxScale().- Parameters:
multiplicand- value to be multiplied by thisMonetaryAmount. If the multiplicand's scale exceeds the capabilities of the implementation, it may be rounded implicitly.- Returns:
this * multiplicand- Throws:
java.lang.ArithmeticException- if the result exceeds the numeric capabilities of this implementation class, i.e. theMonetaryContextcannot be adapted as required.
-
divide
Returns aMonetaryAmountwhose value isthis / divisor, and whose preferred scale isthis.getContext().getMaxScale() - divisor.getContext().getMaxScale(); if the exact quotient cannot be represented anArithmeticExceptionis thrown.- Parameters:
divisor- value by which thisMonetaryAmountis to be divided.- Returns:
this / divisor- Throws:
java.lang.ArithmeticException- if the exact quotient does not have a terminating decimal expansion, or if the result exceeds the numeric capabilities of this implementation class, i.e. theMonetaryContextcannot be adapted as required.
-
divide
Returns aMonetaryAmountwhose value isthis / divisor, and whose preferred scale isthis.getContext().getMaxScale() - divisor.getContext().getMaxScale(); if the exact quotient cannot be represented anArithmeticExceptionis thrown.- Parameters:
divisor- value by which thisMonetaryAmountis to be divided.- Returns:
this / divisor- Throws:
java.lang.ArithmeticException- if the exact quotient does not have a terminating decimal expansion, or if the result exceeds the numeric capabilities of this implementation class, i.e. theMonetaryContextcannot be adapted as required.
-
divide
Returns aMonetaryAmountwhose value isthis / divisor, and whose preferred scale isthis.getContext().getMaxScale() - divisor.getContext().getMaxScale(); if the exact quotient cannot be represented anArithmeticExceptionis thrown.- Parameters:
divisor- value by which thisMonetaryAmountis to be divided.- Returns:
this / divisor- Throws:
java.lang.ArithmeticException- if the exact quotient does not have a terminating decimal expansion, or if the result exceeds the numeric capabilities of this implementation class, i.e. theMonetaryContextcannot be adapted as required.
-
remainder
Returns aMonetaryAmountwhose value isthis % divisor.The remainder is given by
this.subtract(this.divideToIntegralValue(divisor).multiply(divisor). Note that this is not the modulo operation (the result can be negative).- Parameters:
divisor- value by which thisMonetaryAmountis to be divided.- Returns:
this % divisor.- Throws:
java.lang.ArithmeticException- ifdivisor==0, or if the result exceeds the numeric capabilities of this implementation class, i.e. theMonetaryContextcannot be adapted as required.
-
remainder
Returns aMonetaryAmountwhose value isthis % divisor.The remainder is given by
this.subtract(this.divideToIntegralValue(divisor).multiply(divisor). Note that this is not the modulo operation (the result can be negative).- Parameters:
divisor- value by which thisMonetaryAmountis to be divided.- Returns:
this % divisor.- Throws:
java.lang.ArithmeticException- ifdivisor==0, or if the result exceeds the numeric capabilities of this implementation class, i.e. theMonetaryContextcannot be adapted as required.
-
remainder
Returns aMonetaryAmountwhose value isthis % divisor.The remainder is given by
this.subtract(this.divideToIntegralValue(divisor).multiply(divisor). Note that this is not the modulo operation (the result can be negative).- Parameters:
divisor- value by which thisMonetaryAmountis to be divided.- Returns:
this % divisor.- Throws:
java.lang.ArithmeticException- ifdivisor==0, or if the result exceeds the numeric capabilities of this implementation class, i.e. theMonetaryContextcannot be adapted as required.
-
divideAndRemainder
Returns a two-elementMonetaryAmountarray containing the result ofdivideToIntegralValuefollowed by the result ofremainderon the two operands.Note that if both the integer quotient and remainder are needed, this method is faster than using the
divideToIntegralValueandremaindermethods separately because the division need only be carried out once.- Parameters:
divisor- value by which thisMonetaryAmountis to be divided, and the remainder computed.- Returns:
- a two element
MonetaryAmountarray: the quotient (the result ofdivideToIntegralValue) is the initial element and the remainder is the final element. - Throws:
java.lang.ArithmeticException- ifdivisor==0, or if the result exceeds the numeric capabilities of this implementation class, i.e. theMonetaryContextcannot be adapted as required.- See Also:
divideToIntegralValue(long),remainder(long)
-
divideAndRemainder
Returns a two-elementMonetaryAmountarray containing the result ofdivideToIntegralValuefollowed by the result ofremainderon the two operands.Note that if both the integer quotient and remainder are needed, this method is faster than using the
divideToIntegralValueandremaindermethods separately because the division need only be carried out once.- Parameters:
divisor- value by which thisMonetaryAmountis to be divided, and the remainder computed.- Returns:
- a two element
MonetaryAmountarray: the quotient (the result ofdivideToIntegralValue) is the initial element and the remainder is the final element. - Throws:
java.lang.ArithmeticException- ifdivisor==0, or if the result exceeds the numeric capabilities of this implementation class, i.e. theMonetaryContextcannot be adapted as required.- See Also:
divideToIntegralValue(double),remainder(double)
-
divideAndRemainder
Returns a two-elementMonetaryAmountarray containing the result ofdivideToIntegralValuefollowed by the result ofremainderon the two operands.Note that if both the integer quotient and remainder are needed, this method is faster than using the
divideToIntegralValueandremaindermethods separately because the division need only be carried out once.- Parameters:
divisor- value by which thisMonetaryAmountis to be divided, and the remainder computed.- Returns:
- a two element
MonetaryAmountarray: the quotient (the result ofdivideToIntegralValue) is the initial element and the remainder is the final element. - Throws:
java.lang.ArithmeticException- ifdivisor==0, or if the result exceeds the numeric capabilities of this implementation class, i.e. theMonetaryContextcannot be adapted as required.- See Also:
divideToIntegralValue(Number),remainder(Number)
-
divideToIntegralValue
Returns aMonetaryAmountwhose value is the integer part of the quotientthis / divisorrounded down. The preferred scale of the result isthis.getContext().getMaxScale() - divisor.getContext().getMaxScale().- Parameters:
divisor- value by which thisBigDecimalis to be divided.- Returns:
- The integer part of
this / divisor. - Throws:
java.lang.ArithmeticException- ifdivisor==0- See Also:
BigDecimal.divideToIntegralValue(java.math.BigDecimal)
-
divideToIntegralValue
Returns aMonetaryAmountwhose value is the integer part of the quotientthis / divisorrounded down. The preferred scale of the result isthis.getContext().getMaxScale() - divisor.getContext().getMaxScale().- Parameters:
divisor- value by which thisBigDecimalis to be divided.- Returns:
- The integer part of
this / divisor. - Throws:
java.lang.ArithmeticException- ifdivisor==0- See Also:
BigDecimal.divideToIntegralValue(java.math.BigDecimal)
-
divideToIntegralValue
Returns aMonetaryAmountwhose value is the integer part of the quotientthis / divisorrounded down. The preferred scale of the result isthis.getContext().getMaxScale() - divisor.getContext().getMaxScale().- Parameters:
divisor- value by which thisBigDecimalis to be divided.- Returns:
- The integer part of
this / divisor. - Throws:
java.lang.ArithmeticException- ifdivisor==0- See Also:
BigDecimal.divideToIntegralValue(java.math.BigDecimal)
-
scaleByPowerOfTen
Returns aMonetaryAmountwhose numerical value is equal to (this* 10n). The scale of the result isthis.getContext().getMaxScale() - n.- Parameters:
power- the power.- Returns:
- the calculated amount value.
- Throws:
java.lang.ArithmeticException- if the scale would be outside the range of a 32-bit integer, or if the result exceeds the numeric capabilities of this implementation class, i.e. theMonetaryContextcannot be adapted as required.
-
abs
MonetaryAmount abs()Returns aMonetaryAmountwhose value is the absolute value of thisMonetaryAmount, and whose scale isthis.getContext().getMaxScale().- Returns:
abs(this
-
negate
MonetaryAmount negate()Returns aMonetaryAmountwhose value is-this, and whose scale isthis.getContext().getMaxScale(), with rounding according to the context settings.- Returns:
-this, rounded as necessary.- Throws:
java.lang.ArithmeticException- if rounding fails.- See Also:
BigDecimal.negate()
-
plus
MonetaryAmount plus()Returns aMonetaryAmountwhose value is+this.This method, which simply returns this
MonetaryAmountis included for symmetry with the unary minus methodnegate().- Returns:
this.- See Also:
negate(),BigDecimal.plus()
-
stripTrailingZeros
MonetaryAmount stripTrailingZeros()Returns aMonetaryAmountwhich is numerically equal to this one but with any trailing zeros removed from the representation. For example, stripping the trailing zeros from theMonetaryAmountvalueCHF 600.0, which has [BigInteger,scale] components equals to [6000, 1], yields6E2with [BigInteger,scale] components equals to [6, -2]- Returns:
- a numerically equal
MonetaryAmountwith any trailing zeros removed.
-