Search code examples
javabigdecimal

Creating a custom BigDecimal type


In my application, all BigDecimal numbers are scaled to have two decimal places.. In other words, everytime I create a new BigDecimal in my code, I need to use the method scale too:

BigDecimal x = BigDecimal.ZERO;
x.setScale(2, RoundingMode.HALF_UP);

So, to minimize the work, I wanted to create my custom BigDecimal type, something like:

public class CustomBigDecimal extends BigDecimal {

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

}

I know this.setScale(2, RoundingMode.HALF_UP); doesn't do the job, but I can't find the way to do it, is it possible?


Solution

  • You could create a CustomBigDecimal that extends from BigDecimal. However, as BigDecimal is immutable, you would never inherit state (such as the scale and rounding mode) from the parent class.

    I'd go for the utility class suggested in another answer, or maybe a wrapper that delegates every operation to an actual BigDecimal instance. The downside of this approach is that your brand new CustomBigDecimal wouldn't be a BigDecimal, so they wouldn't be interchangeable.

    EDIT: a downside of this approach is that you have to delegate about 50 methods. Not the end of the world with a good IDE, but definitely not very appealing...

    If, after all, you still want to make CustomBigDecimal inherit from BigDecimal, you'd need to use a decorator approach:

    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
    
    }