Подтвердить что ты не робот

Использование общего типа с 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.class вместо T. Я уверен, что проблема связана с отсутствием понимания типов 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);
}
4b9b3361

Ответ 1

Самый простой подход к тому, что вы пытаетесь, - это определить тип класса, который должен быть возвращен в самой сигнатуре метода. Вы можете сделать это, либо передав экземпляр "T" методу, либо класс возвращаемого значения. Второй подход более типичен в тех случаях, когда вы ожидаете генерировать возвращаемое значение. Вот пример такого подхода с использованием 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);

Ответ 2

Чтобы получить тип времени выполнения List<T>, учитывая класс 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
        }
    };

Ответ 3

Я использую этот метод для чтения и записи объекта с использованием 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);