Gson.toJson() и наследование от универсального класса

У меня есть следующий класс:

public static class TestSomething {

    Integer test;

    public TestSomething(Integer test) {
        this.test = test;
    }

    // getter and setter for test
}

Хорошо, теперь создайте коллекцию этого класса и сериализуйте ее с помощью Gson:

Collection<TestSomething> tests = Arrays.asList(
    new TestSomething(1), 
    new TestSomething(2), 
    new TestSomething(3)
);
String json = new Gson().toJson(tests, new TypeToken<Collection<TestSomething>>() {}.getType());

После этого строка json установлен в

[{"test":1},{"test":2},{"test":3}]

Что здорово.

Но теперь все мои классы моделей наследуются от универсального типа Identifiable<T> который обеспечивает только два метода T getId() а также void setId(T), Так что я меняю TestSomething-класс сверху до

public static class TestSomething extends Identifiable<Long> {
    // same as above
}

Когда я пытаюсь это объяснить Gson.toJson()Gson заканчивается следующим исключением:

java.lang.UnsupportedOperationException: Expecting parameterized type, got class path.to.TestSomething.
 Are you missing the use of TypeToken idiom?
 See http://sites.google.com/site/gson/gson-user-guide#TOC-Serializing-and-Deserializing-Gener
        at com.google.gson.TypeInfoFactory.getActualType(TypeInfoFactory.java:97)
        ...

Итак, что мне нужно сделать, чтобы получить эту работу?

2 ответа

Я не знаю ответа, но я знаю, что универсальное разрешение типов - это непростая задача: определиться с полным разрешением типов от интерфейса с параметром типа T до объявления универсального параметра (T=Long). В этих случаях недостаточно проверять параметры объекта Method, но также разрешать параметры универсального типа. Это наиболее вероятно, что вызывает проблемы; это может быть ошибка в Gson.

Поскольку вы сериализуете вещи, возможно, вы могли бы просто пропустить любые объявления типов? Хотя ваш TypeToken подходит для варианта использования, возможно, он сбивает с толку Gson.

Но на случай, если вы не сможете заставить Gson работать с этим, я знаю, что из других библиотек JSON Джексон может правильно обрабатывать такие случаи.

Возможно, эта проблема была решена в одном из выпусков Gson, более новых, чем тот, который использовался первоначальным спрашивающим, поскольку пример в исходном вопросе теперь сериализуется, как и ожидалось.

// output: 
// [{"test":1},{"test":2},{"test":3}]

import java.util.Arrays;
import java.util.Collection;

import com.google.gson.Gson;
import com.google.gson.reflect.TypeToken;

public class Foo
{
  public static void main(String[] args)
  {
    Collection<TestSomething> tests = Arrays.asList(
        new TestSomething(1),
        new TestSomething(2),
        new TestSomething(3));
    String json = new Gson().toJson(tests, new TypeToken<Collection<TestSomething>>() {}.getType());
    System.out.println(json);
  }
}

class TestSomething extends Identifiable<Long>
{
  Integer test;

  public TestSomething(Integer test)
  {
    this.test = test;
  }

  @Override
  Long getId()
  {
    return new Long(test);
  }

  @Override
  void setId(Long t)
  {
    this.test = (int)(t.longValue());
  }
}

abstract class Identifiable<T>
{
  abstract T getId();
  abstract void setId(T t);
}
Другие вопросы по тегам