ジェネリック クラス変数のデシリアライズ
...
ジャクソンにどのように伝えますか? gsonはもっとうまくやりますか?
Gson ユーザー ガイドには、達成しようとしていることを正確に理解しているセクションが含まれていますが、その文書化された例はまだ不完全な場合があります。
ブログ投稿で、Gson 1.7.1 を使用したソリューションについて詳しく説明しました。 以下は、関連するコード例です。
Jackson (1.8.2) を使用した同様の (しかしより複雑な) ソリューションも、同じブログ投稿で実証および説明されています。(さまざまなアプローチと例で数百行のコードが使用されているため、ここでの再投稿は省略しています。)
public class GsonInstanceCreatorForParameterizedTypeDemo
{
public static void main(String[] args)
{
Id<String> id1 = new Id<String>(String.class, 42);
Gson gson = new GsonBuilder().registerTypeAdapter(Id.class,
new IdInstanceCreator()).create();
String json1 = gson.toJson(id1);
System.out.println(json1);
// actual output: {"classOfId":{},"value":42}
// This contradicts what the Gson docs say happens.
// With custom serialization, as described in a
// previous Gson user guide section,
// intended output may be
// {"value":42}
// input: {"value":42}
String json2 = "{\"value\":42}";
Type idOfStringType=new TypeToken<Id<String>>(){}.getType();
Id<String> id1Copy = gson.fromJson(json2, idOfStringType);
System.out.println(id1Copy);
// output: classOfId=class java.lang.String, value=42
Type idOfGsonType = new TypeToken<Id<Gson>>() {}.getType();
Id<Gson> idOfGson = gson.fromJson(json2, idOfGsonType);
System.out.println(idOfGson);
// output: classOfId=class com.google.gson.Gson, value=42
}
}
class Id<T>
{
private final Class<T> classOfId;
private final long value;
public Id(Class<T> classOfId, long value)
{
this.classOfId = classOfId;
this.value = value;
}
@Override
public String toString()
{
return "classOfId=" + classOfId + ", value=" + value;
}
}
class IdInstanceCreator implements InstanceCreator<Id<?>>
{
@SuppressWarnings({ "unchecked", "rawtypes" })
public Id<?> createInstance(Type type)
{
Type[] typeParameters =
((ParameterizedType) type).getActualTypeArguments();
Type idType = typeParameters[0];
return new Id((Class<?>) idType, 0L);
}
}