创建自定义BigDecimal类型

yat*_*at0 16 java bigdecimal

在我的应用程序中,所有BigDecimal数字都缩放为两位小数.换句话说,每次我在代码中创建一个新的BigDecimal时,我也需要使用方法比例:

BigDecimal x = BigDecimal.ZERO;
x.setScale(2, RoundingMode.HALF_UP);
Run Code Online (Sandbox Code Playgroud)

因此,为了最大限度地减少工作量,我想创建自定义BigDecimal类型,例如:

public class CustomBigDecimal extends BigDecimal {

    public CustomBigDecimal(String val) {
        super(val);
        this.setScale(2, RoundingMode.HALF_UP);
    }

}
Run Code Online (Sandbox Code Playgroud)

我知道this.setScale(2, RoundingMode.HALF_UP);不做这项工作,但我找不到办法,是否有可能?

Mar*_*ren 15

您可以简单地为自己创建一个方法,创建一个零的BigDecimal.就像是:

public static BigDecimal scaled(String val) {
    BigDecimal x = new BigDecimal(val);
    return x.setScale(2, RoundingMode.HALF_UP);
}
Run Code Online (Sandbox Code Playgroud)

把它放在一个帮助器类中,比如BigDecimalHelper,BigDecimalFactory等等.:)

编辑:稍微改变它以返回setScale的结果,因为BigDecimal是不可变的.并进一步回答原始问题:由于没有使用setScale()更改对象的状态,因此无法编写您所编写的内容.

  • 它可能是子类化的(如果BigDecimal没有被声明为final,它可能应该是因为它应该是不可变的),但它不会解决你的问题,因为它的状态在创建后不能改变.如果你想要一个自定义类型,我会选择*具有*BigDecimal而不是*is*one.这样,您可以在构造函数中创建BigDecimal并更改其状态.:) (3认同)
  • 也许最好为您的用例创建一个特殊类型.例如货币类型 (2认同)

Fed*_*ner 8

你可以创建一个CustomBigDecimal扩展自BigDecimal.但是,由于BigDecimal不可变,您永远不会从父类继承状态(例如缩放和舍入模式).

我会去另一个答案中建议的实用程序类,或者可能是一个将每个操作委托给一个实际BigDecimal实例的包装器.这种方法的缺点是你的全新CustomBigDecimal不会是一个BigDecimal,所以它们不可互换.

编辑:这种方法的缺点是你必须委托约50种方法.不是世界末日有一个好的IDE,但绝对不是很吸引人......

毕竟,如果你仍想CustomBigDecimal继承BigDecimal,你需要使用装饰器方法:

public class CustomBigDecimal extends BigDecimal {

    private final BigDecimal value;

    private CustomBigDecimal(BigDecimal value) {
        super(value.toPlainString()); // needed to compile, 
                                      // useless except for implicit null-check
        this.value = value;
    }

    public CustomBigDecimal(String val) {
        this(new BigDecimal(val).setScale(2, RoundingMode.HALF_UP));
    }

    @Override
    public CustomBigDecimal abs() {
        return new CustomBigDecimal(this.value.abs());
    }

    // TODO all other methods

}
Run Code Online (Sandbox Code Playgroud)


Dan*_*mes 7

例如,您可以存储MathContext的单例实例,并将它们用作BigDecimal构造函数的参数.

通常你可以这样做:

MathContext context = new MathContext(2, RoundingMode.HALF_UP);
BigDecimal number = new BigDecimal(val, context);
Run Code Online (Sandbox Code Playgroud)

因此,如果您将MathContext作为单例,则可以执行以下操作:

BigDecimal number = new BigDecimal(val, MathInstanceHolder.getMathContext());
Run Code Online (Sandbox Code Playgroud)

MathInstanceHolder包含MathContext实例的位置.