@ Решение Maciek отлично работает, если объявленная переменная-член типа является интерфейсом / абстрактным классом. Это не будет работать, если объявленный тип является подклассом / субинтерфейсом / субабстрактным классом, если мы не зарегистрируем их все через registerTypeAdapter()
. Мы можем избежать регистрации по одному с использованием registerTypeHierarchyAdapter
, но я понимаю, что это вызовет StackOverflowError
из-за бесконечного цикла. (Пожалуйста, прочитайте справочный раздел ниже)
Короче говоря, мое обходное решение выглядит немного бессмысленным, но оно работает без StackOverflowError
.
@Override
public JsonElement serialize(T object, Type interfaceType, JsonSerializationContext context) {
final JsonObject wrapper = new JsonObject();
wrapper.addProperty("type", object.getClass().getName());
wrapper.add("data", new Gson().toJsonTree(object));
return wrapper;
}
Я использовал другой новый Gson
экземпляр работы в качестве сериализатора / десериализатора по умолчанию, чтобы избежать бесконечного цикла. Недостатком этого решения является то, что вы также потеряете другие TypeAdapter
, если у вас есть настраиваемая сериализация для другого типа, и он появляется в объекте, он просто потерпит неудачу.
Тем не менее, я надеюсь на лучшее решение.
Ссылки
Согласно документации Gson 2.3.1 для JsonSerializationContext
и JsonDeserializationContext
Вызывает сериализацию по умолчанию для указанного объекта, передавая информацию определенного типа. Он никогда не должен вызываться для элемента, полученного в качестве параметра метода JsonSerializer.serialize (Object, Type, JsonSerializationContext). Это приведет к бесконечному циклу, поскольку Gson, в свою очередь, снова вызовет пользовательский сериализатор.
и
Вызывает десериализацию по умолчанию для указанного объекта. Он никогда не должен вызываться для элемента, полученного в качестве параметра метода JsonDeserializer.deserialize (JsonElement, Type, JsonDeserializationContext). Это приведет к бесконечному циклу, поскольку Gson, в свою очередь, снова вызовет пользовательский десериализатор.
Отсюда следует, что приведенная ниже реализация вызовет бесконечный цикл и в конечном итоге приведет к StackOverflowError
.
@Override
public JsonElement serialize(Animal src, Type typeOfSrc,
JsonSerializationContext context) {
return context.serialize(src);
}