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の場合

BigDecimalBigDecimal精度で扱えるようなので、 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以下の精度と考えておいた方が良いだろう。