web-dev-qa-db-ja.com

Gsonでジェネリック型を使用する

Google Gson で使用する汎用クラスを作成しようとしています。クラス_GsonJsonConverterImplementation<T>_を作成しました。このクラスには次のメソッドがあります。

_public T deserialize(String jsonString) {
    GsonBuilder builder = new GsonBuilder();
    builder.setDateFormat("MM/dd/yy HH:mm:ss");

    Gson gson = builder.create();
    return gson.fromJson(jsonString, T); // T.class etc. what goes here
}
_

目標は、このメソッドが、GsonJsonConverterImplementationで設定したどのタイプでも処理できるようにすることです。残念ながら、gson.fromJson(jsonString, T)は機能せず、Tの代わりに_T.class_を使用することもできません。この問題は、Javaジェネリック型を理解していないことが原因であると確信しています。 。Gsonでジェネリックを使用する正しい方法は何ですか?

編集
クリスの答えを使用して 私はこれがうまくいくと思います。残念ながら、clazzはこの方法では使用できず、コンパイラエラーが発生します。 Gsonでコレクションとジェネリック型を操作するためのオプションは何ですか?

_public List<T> deserializeList(String jsonString, Class<T> clazz) {
    GsonBuilder builder = new GsonBuilder();
    builder.setDateFormat("MM/dd/yy HH:mm:ss");
    Gson gson = builder.create();

    Type listType = new TypeToken<clazz>(){}.getType(); // compiler error

    return gson.fromJson(jsonString, listType);
}
_
26
ahsteele

あなたが試みている最も簡単なアプローチは、メソッドのシグネチャ自体に返されるクラスのタイプを定義することです。これを行うには、メソッドに 'T'のインスタンスを渡すか、返される値のクラスを渡します。 2番目の方法は、戻り値を生成することが予想される場合により一般的です。 Gsonを使用したこのアプローチの例を次に示します。

public <T> T deserialize(String jsonString, Class<T> clazz) {
    GsonBuilder builder = new GsonBuilder();
    builder.setDateFormat("MM/dd/yy HH:mm:ss");

    Gson gson = builder.create();
    return gson.fromJson(jsonString, clazz);
}

使用法:

MyClass mc = deserialize(jsonString, MyClass.class);
36
Kris Babic

Tのクラスが指定されている場合、List<T>のランタイムタイプを取得するには、JDKが必要とは考えなかったためサポートしません。あなたはParameterizedTypeをサブクラス化することができますが、それは本当にうんざりです。

    Type typeListT = new ParameterizedType()
    {
        public Type[] getActualTypeArguments()
        {
            return new Type[]{clazz};
        }
        public Type getRawType()
        {
            return List.class;
        }
        public Type getOwnerType()
        {
            return null;
        }
        public boolean equals(Object obj)
        {
            // must implement equals per spec. this sucks
        }
        public int hashCode()
        {
            // this blows! Java forgot to specific it!
            // since we override equals, we should override hashCode
            // we have no idea what value should be returned here!
            // note we are co-existing with other ParameterizedType impls
        }
    };
5
irreputable

これらのメソッドを使用して、GSONを使用したオブジェクトの読み取りと書き込みを行っています。

public static <T> void saveAnyTypeOfObject(String key, T value){
        Gson gson = new Gson();
        String json = gson.toJson(value);
        SharedPref.save(key, json);
    }
    //Type listType = new TypeToken<YourClass>(){}.getType();
    public static <T> T readAnyTypeOfObject(String key, Type tt) {
        Gson gson = new Gson();
        String json = SharedPref.read(key, "{}");
        T obj = gson.fromJson(json, tt);
        return obj;
    }

読みます

  TypeToken<YourClassName> typeToken= new TypeToken<YourClassName>() {};
  YourClassName yourClassName = ListSharedPref.readAnyTypeOfObject("keyForSavingClass", typeToken.getType());

そしてそれを好きに保存してください

YourClassName yourClassName = gson.fromJson(objJsonObject.toString(),YourClassName.class);               
ListSharedPref.saveAnyTypeOfObject("keyForSavingClass",yourClassName);
1
Xar E Ahmer