对于未知的Number类型,Groovy NumberMath默认为IntegerMath

时间:2015-05-05 09:21:49

标签: groovy spock

我们有一个名为“Decimal”的自定义类型,它扩展了java.lang.Number

我们正在使用Groovy / Spock进行一些单元/验收测试。

我们在断言中注意到了一些神秘的行为。

在以下代码中,myDecimal的真值为9.91

assert myDecimal == new Decimal(“9.91”)   // succeed. 
assert myDecimal == new Decimal(“9.02”)   // succeed. What??
assert myDecimal == new Decimal(“8.99”)   // fail. 

我们的一位开发人员在org.codehaus.groovy.runtime.typehandling.NumberMath.java中找到了一些代码[groovy-all-2.2.1]

public static NumberMath getMath(Number left, Number right) {
    if (isFloatingPoint(left) || isFloatingPoint(right)) {
        return FloatingPointMath.INSTANCE;
    }
    if (isBigDecimal(left) || isBigDecimal(right)) {
        return BigDecimalMath.INSTANCE;
    }
    if (isBigInteger(left) || isBigInteger(right)) {
        return BigIntegerMath.INSTANCE;
    }
    if (isLong(left) || isLong(right)){
        return LongMath.INSTANCE;
    }
    return IntegerMath.INSTANCE;
}

看到这个方法很明显,我们的自定义Decimal类将被分配一个IntegerMath。在断言非整数时会导致“破坏”的断言。

有没有人知道解决这个问题的方法?例如有没有办法提供NumberMath对象的自定义工厂?

任何帮助都会非常感激。

1 个答案:

答案 0 :(得分:0)

我看到两种解决方法:  1.如果其中一个可用的Math实例(比如BigDecimalMath)可以正确地比较您的数字,那么相应地更改Decimal的基类  2.否则,尝试更改NumberMath的元类中的getMath方法。它很脏,我甚至不确定是否可以使用Metaclass改变Groovy本身。那就是说,我想在一个空闲时刻检查出来......