Использование универсального типа с Gson - PullRequest
26 голосов
/ 20 марта 2011

Я пытаюсь создать универсальный класс для использования с 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);
}

Ответы [ 3 ]

36 голосов
/ 20 марта 2011

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

Чтобы получить тип времени выполнения 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
        }
    };
1 голос
/ 06 апреля 2017

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