Groovy 1.8.4 から 1.8.5 にアップグレードすると、JsonSlurper は Json の数値に対して float または double ではなく BigDecimal を返します。たとえば、次の JSON ドキュメントについて考えてみます。
{"person":{"name":"Guillaume","age":33.4,"pets":["dog","cat"]}}
Groovy 1.8.4 では「age」は float として表されますが、Groovy 1.8.5+ では BigDecimal として表されます。内部で Groovy JsonSlurper を使用するJava フレームワークを作成したので、下位互換性を維持するために、JSON 数値 (33.4 など) を透過的に float または double に変換したいと考えています。groovy-json ソース コードを見ると、JsonSluper は、「getValue()」メソッドで 33.4 から BigDecimal を作成する JsonToken を使用していることがわかります。このメソッドは、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
}
問題は、JsonToken でオーバーライドされた「getValue()」が呼び出される前に上記のコードが実行されてもnew JsonSluper().parseText(..)
(代わりに元の getValue() メソッドが呼び出される) ことです。しかし、JsonSlurper クラスのすべてのコードを自分のクラスにコピーすると、それを JsonSlurper2 と呼び、new JsonSluper2().parseText(..)
"getValue()" のオーバーライドされたメソッドが呼び出され、すべてが期待どおりに機能します。どうしてこれなの?JsonSlurper を自分のクラスにコピーしないようにするにはどうすればよいですか?