0

经过一番折腾,我想出了以下代码,将任何 Number 子类转换为 BigDecimal。

然而,我不相信这段代码是完全正确的。我当然不高兴它有多冗长!

有没有更好的方法来做到这一点,这种方法是否有任何我需要注意的陷阱(除了我已经知道的浮点不精确表示问题)?

public DecimalSpec setValue (Number value) {
    if (value instanceof Double) {
        if ((((Double) value).isNaN ())
        || (((Double) value).isInfinite ())) {
            throw new IllegalArgumentException ("Infinite or NaN values not allowed");
        }
    }
    this.value  = new BigDecimal (value.toString ());
    return this;
}
4

2 回答 2

2

我不知道有什么方法可以用更少的代码来编写它,就像某些方法可以缩短部分代码一样。但是,我可能会重载 for 的方法Double,或者让BigDecimalthrow aNumberFormatException代替。

BigDecimal工作:

/** May throw NumberFormatException or NullPointerException. */
public DecimalSpec setValue (Number value) {
    this.value  = new BigDecimal (value.toString ());
    return this;
}

重载Double

/** May throw NullPointerException. */
public DecimalSpec setValue (Number value) {
    this.value  = new BigDecimal (value.toString ());
    return this;
}

/** May throw NullPointerException or IllegalArgumentException. */
public DecimalSpec setValue (Double value) {
    if (value.isNaN () || value.isInfinite ()) {
        throw new IllegalArgumentException ("Infinite or NaN values not allowed");
    }
    return this.setValue ((Number) value);
}
于 2013-08-30T23:53:32.567 回答
1

我认为你有一个设计问题。做setValue一个BigDecimal开始。然后将其他类型转换为的代码BigDecimal可以在您的代码中的其他位置。您可以自由重载BigDecimal各种类型的转换,并且可以BigDecimal根据输入类型专门进行转换。

例如,

public class BigDecimalConverter {
    public static toBigDecimal(int i) { ... }
    public static toBigDecimal(double i) { ... }
    ...
}

然后

public DecimalSpec setValue (BigDecimal value) {
    this.value  = value;
    return this;
}

decimalSpec.setValue(BigDecimalConverter.toBigDecimal(myNumber));

当然,这并不完美,但这是一般的想法。一段代码永远不应该做太多的工作。如果在某些时候需要接受未知类型进行转换,您可能会考虑使用转换器interface,然后使用工厂类(可能不是正确的模式名称)来为您提供正确的类型。

于 2013-08-30T23:19:06.833 回答