我可以在Groovy中使用ExpandoMetaClasses吗?

时间:2013-02-05 19:30:46

标签: groovy metaprogramming

从Groovy 1.8.4升级到1.8.5时,JsonSlurper为Json中的数字返回BigDecimal而不是float或double。例如,请考虑以下JSON文档:

{"person":{"name":"Guillaume","age":33.4,"pets":["dog","cat"]}} 

在Groovy 1.8.4中,“age”将表示为float,而在Groovy 1.8.5+中则表示为BigDecimal。我创建了一个Java framework,它使用了Groovy JsonSlurper,以便保持向后兼容性,我想将JSON数字(例如33.4)转换为float或double透明。看了一下groovy-json源代码后,我看到JsonSluper使用了一个JsonToken,它在“getValue()”方法中创建了一个33.4的BigDecimal。此方法由JsonSlurper实例调用。

那么(我想)我想要做的是覆盖JsonToken类中的getValue()方法,让它返回一个float或double。这就是我尝试过的:

    def original = JsonToken.metaClass.getMetaMethod("getValue")
    JsonToken.metaClass.getValue = {->
        def result = original.invoke(delegate)

        // Convert big decimal to float or double
        if (result instanceof BigDecimal) {
            if (result > Float.MAX_VALUE) {
                result = result.doubleValue();
            } else {
                result = result.floatValue();
            }
        }
        result
    }

问题在于,即使上面描述的代码在new JsonSluper().parseText(..)之前执行,也没有调用JsonToken中被覆盖的“getValue()”(而是调用原始的getValue()方法)。但是,如果我将JsonSlurper类中的所有代码复制到我自己的类中,我们将其称为JsonSlurper2,并且new JsonSluper2().parseText(..)调用“getValue()”的重写方法,并且一切都按预期工作。为什么是这样?为了避免将JsonSlurper复制到我自己的类,我需要做些什么?

1 个答案:

答案 0 :(得分:1)

JsonSlurper是一个Java类,因此您无法通过metaClass覆盖其方法。请参阅this mailing list thread

This question看起来可能有办法让你这样做。