BigDecimal for money和BigDecimal之间的百分比差异

时间:2014-05-10 23:26:15

标签: java inheritance bigdecimal

我在整个应用程序中使用BigDecimal来处理百分比。但是,我需要一种方法来区分两者之间的使用(为了呈现它们,即在JTable中)。所以,我最初的想法是编写两个类似于BigDecimal的类,以便我可以对它们进行instanceof测试。所以我写了这段代码:

DollarValue.java:

import java.math.BigDecimal;

public class DollarValue extends BigDecimal {

}

PercentValue.java:

import java.math.BigDecimal;

public class PercentValue extends BigDecimal {

}

但是,为了使用构造函数(because they cannot be inherited),我需要手动覆盖每个构造函数。所以,DollarValue.java变成了一个怪物:

import java.math.BigDecimal;
import java.math.BigInteger;
import java.math.MathContext;

public class DollarValue extends BigDecimal {

    public DollarValue(char[] in, int offset, int len) {
        super(in, offset, len);
    }
    public DollarValue(char[] in, int offset, int len, MathContext mc) {
        super(in, offset, len, mc);
    }
    public DollarValue(char[] in) {
        super(in);
    }
    public DollarValue(char[] in, MathContext mc) {
        super(in, mc);
    }
    public DollarValue(String val) {
        super(val);
    }
    public DollarValue(String val, MathContext mc) {
        super(val, mc);
    }
    public DollarValue(double val) {
        super(val);
    }
    public DollarValue(double val, MathContext mc) {
        super(val, mc);
    }
    public DollarValue(BigInteger val) {
        super(val);
    }
    public DollarValue(BigInteger val, MathContext mc) {
        super(val, mc);
    }
    public DollarValue(BigInteger unscaledVal, int scale) {
        super(unscaledVal, scale);
    }
    public DollarValue(BigInteger unscaledVal, int scale, MathContext mc) {
        super(unscaledVal, scale, mc);
    }
    public DollarValue(int val) {
        super(val);
    }
    public DollarValue(int val, MathContext mc) {
        super(val, mc);
    }
    public DollarValue(long val) {
        super(val);
    }
    public DollarValue(long val, MathContext mc) {
        super(val, mc);
    }
}

但更糟糕的是,在实现中,这不起作用,因为我经常使用静态BigDecimal代码。举例说明:

public static void main(String[] args) {
    DollarValue dollars = DollarValue.ONE;
    DollarValue dollars2 = DollarValue.valueOf(25);
}

会抛出错误,因为DollarValue.ONE实际上是BigDecimal,而不是DollarValueDollarValue#valueOf()也会返回BigDecimal

所以现在我没有想法。在我试图实现的方式中区分同一类的两个实现的最简单方法是什么?这似乎是一个简单的问题...

编辑:任何允许我在渲染器中自动区分两者的解决方案也可以。例如,我需要将值提供给JTable,并让JTable显示钱的美元符号$或百分比的百分号%

2 个答案:

答案 0 :(得分:1)

使用组合,而不是继承。在BigDecimal中执行所有算术,但是有两个类,每个类都有一个带有BigDecimal参数的构造函数和一个返回BigDecimal的getValue方法。

代码看起来会更复杂:

DollarValue dollars = new DollarValue(BigDecimal.ONE);
DollarValue dollars2 = new DollarValue(BigDecimal.valueOf(25));
DollarValue sum = new DollarValue(dollars.getValue().add(dollars2.getValue()));

如果其中一个类有一些非常常见的操作,请直接在该类中实现。例如,DollarValue可能有:

public DollarValue sum(DollarValue other) {
  return new DollarValue(getValue().add(other.getValue()));
}

答案 1 :(得分:1)

我强烈建议使用Joda-Money库来处理钱,而不是试图自己重新发明轮子。使用金钱是一个常见且棘手的问题。让其他人为你解决。

为项目添加新的依赖项总是有点令人沮丧,但是当涉及到提供明显但难以实现的优点的核心实用程序库时,它应该是一个明智的选择。其他一些关键库是:

  • Guava - 这绝对应该是任何现代Java代码库的一部分。提供的实用程序和新集合具有不可替代的价值。
  • Joda-Time(除非你在Java 8上) - 就像金钱一样,时间是一个非常棘手的数据结构来正确表示(因为Java的长期Calendar和相关的类证明了)而Joda-Time提供了一个强大而深思熟虑的界面。

还有许多其他的图书馆我可以称之为值得使用,但如果你不使用这三个,你真的会犯错误。虽然技术上是“非标准的”,但就像你注意到的那样,它们无处不在,它们与Java开发人员工具带的概念上预期不同。