首页 > 解决方案 > BigDecimal 包装器:拥有零静态字段

问题描述

我的自定义Money类是类的一种包装BigDecimalorg.joda.money.Money

和以前一样BigDecimal,我需要Money.ZERO在我的应用程序周围使用 a (通常在reduce()操作中)。

我发现我Money.ZERO在应用程序执行期间所做的更改(也就是说,它的amount值可能不是零)导致无效结果。

下面是我的自定义Money类:

@Getter
@Embeddable
@NoArgsConstructor(access = AccessLevel.PRIVATE)
@AllArgsConstructor(access = AccessLevel.PRIVATE)
public class Money implements Serializable {
    private static final long serialVersionUID = -4274180309004444639L;

    public static final Money ZERO = new Money(BigDecimal.ZERO, CurrencyUnit.EUR);

    private BigDecimal amount;

    @Convert(converter = CurrencyUnitToStringConverter.class)
    private CurrencyUnit currency;

    public static Money of(BigDecimal amount, CurrencyUnit currency) {
        return new Money(amount, currency);
    }

    public Money add(Money addition) {
        checkCurrency(addition);

        amount = amount.add(addition.getAmount());
        return new Money(amount, currency);
    }

    public Money substract(Money reduction) {
        checkCurrency(reduction);

        amount = amount.subtract(reduction.getAmount());
        return new Money(amount, currency);
    }

    private void checkCurrency(Money other) {
        if (!Objects.equal(getCurrency(), other.getCurrency())) {
            throw new IllegalArgumentException("Currency does not match when adding amounts!");
        }
    }

所以我的目标是拥有一个ZERO数量BigDecimal.ZERO永远保持不变的领域。

标签: javastaticwrapper

解决方案


您正在修改内部状态。

看看你的add方法:

public Money add(Money addition) {
    checkCurrency(addition);

    amount = amount.add(addition.getAmount());
    return new Money(amount, currency);
}

在这种方法中,您正在重新分配amount,因此会更改当前Money实例的值。

这是一个简单的修复:

public Money add(Money addition) {
    checkCurrency(addition);

    BigDecimal newAmount = amount.add(addition.getAmount());
    return new Money(newAmount, currency);
}

这同样适用于你的substract方法。


推荐阅读