Java:JSON Jacksonを使ってみる 浮動小数点マッピング編
前回に引き続きJacksonの話題。「Java/JSON Jacksonを使ってみる マッピング編」
Jacksonとは
Jacksonはhttp://jackson.codehaus.org/で開発されている JSONデータをJavaにマッピングするためのライブラリ。
jackson-databindを利用すればJavaオブジェクトへ直接データをマッピングできる。
jacksonを利用するにあたって、どのようにJavaオブジェクトへマッピングされるのかを検証してみました。
Jacksonの浮動小数点マッピングについて
JSONの仕様で疑問点があるのが浮動小数点マッピング。
Javaではfloat/doubleにはじまり10進数浮動小数点のBigDecimal等もあるが、 JSONでは浮動小数点の精度についての取り決めが存在しない。
Jacksonにおいて、それぞれの場合にどのような精度でのマッピングとなるかを検証してみました。
各種浮動小数点の精度とJacksonによるマッピング
floatの場合
ObjectMapper mapper = new ObjectMapper(); Float flt = mapper.readValue("0.123456789123456789", Float.class); System.out.println("value : " + flt); System.out.println("json : " + mapper.writeValueAsString(flt));
value : 0.12345679 json : 0.12345679
float精度まで切り詰められる。
doubleの場合
ObjectMapper mapper = new ObjectMapper(); Double dbl = mapper.readValue("0.123456789123456789", Double.class); System.out.println("value : " + dbl); System.out.println("json : " + mapper.writeValueAsString(dbl));
value : 0.12345678912345678 json : 0.12345678912345678
double精度まで切り詰められる。
BigDecimalの場合
ObjectMapper mapper = new ObjectMapper(); BigDecimal dec = mapper.readValue("0.123456789123456789", BigDecimal.class); System.out.println("value : " + dec); System.out.println("json : " + mapper.writeValueAsString(dec));
value : 0.123456789123456789 json : 0.123456789123456789
なんと、BigDecimal精度で取り扱える。 てっきり、Doubleまで切り詰められると思っていたのでビックリ。
Objectの場合
BigDecimalをBigDecimal精度で扱えるようなので、 Object型の場合も試してみた。
ObjectMapper mapper = new ObjectMapper(); Object obj = mapper.readValue("0.123456789123456789", Object.class); System.out.println("value : " + obj); System.out.println("type : " + obj.getClass().getName()); System.out.println("json : " + mapper.writeValueAsString(obj));
value : 0.12345678912345678 type : java.lang.Double json : 0.12345678912345678
Objectの場合、Double型へ変換されるよう。 予想ではBigDecimalだったのでこちらもビックリ。
まとめ
Jacksonにおいてはfloat/double/BigDecimalについてそれぞれの精度で正確に値を扱えるよう。
しかし、JSONの浮動小数点形式は基本的にJavaScriptの物と考え、 Double以下の精度と考えておいた方が良いだろう。