Ошибка сериализации Gson с val в котлине

1

Я использую Gson v2.8.2 и Retrofit v2.3.0, и у меня есть два класса, Answer.kt:

open class Answer(@SerializedName("answer")
                  var text: String,
                  val id: Int)

и AnswerSummary.kt:

class AnswerSummary(val answer: Answer) : Answer(answer.text, answer.id) {
    val percent: Int = 0
}

Я использую его в списке (на Java, все еще переходя на Kotlin):

public List<AnswerSummary> getAnswerSummaries() {
            return answerSummaries;
        }

Я получаю сообщение об ошибке, когда val не удаляется: class AnswerSummary(val answer: Answer)...:

java.lang.IllegalArgumentException: Unable to create converter for class com.name.app.model.response.AnswerResponse
....
Caused by java.lang.IllegalArgumentException: class com.name.app.model.pojo.AnswerSummary declares multiple JSON fields named answer
       at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory.getBoundFields(ReflectiveTypeAdapterFactory.java:170)
       at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory.create(ReflectiveTypeAdapterFactory.java:100)
       at com.google.gson.Gson.getAdapter(Gson.java:423)
       at com.google.gson.internal.bind.CollectionTypeAdapterFactory.create(CollectionTypeAdapterFactory.java:53)
       ....

После удаления 'val': class AnswerSummary(answer: Answer)... ошибка исчезнет. Почему это так, поскольку я аннотировал только одно поле? - @SerializedName("answer") var text: String.

Я нашел способ обойти сбой, сохраняя неизменность ('val') - используя другое имя переменной: class AnswerSummary(val ans: Answer)... Что происходит за фоном - связано ли это с тем, что значение поля @SerializedName совпадает с именем переменной?

Теги:
kotlin
retrofit2
gson

1 ответ

1
Лучший ответ

Попробуйте переименовать параметр answer:

class AnswerSummary(val ans: Answer) : Answer(ans.text, ans.id) { ... }

или используйте answer качестве параметра, а не свойства:

class AnswerSummary(answer: Answer) : Answer(answer.text, answer.id) { ... }

Это будет работать, потому что, когда вы используете val параметр 'answer' рассматривается как свойство (без val он рассматривается как параметр) и сериализуется Gson, используя имя свойства в качестве сериализованного имени. В то же время у вас есть такое же сериализованное имя @SerializedName("answer") в базовом классе Answer, поэтому при сериализации свойств возникает конфликт.

  • 0
    почему я должен переименовать переменную? потому что @SerializedName - это тоже «ответ»?
  • 0
    да, ошибка «класс com.name.app.model.pojo.AnswerSummary объявляет несколько полей JSON с именем answer» говорит о наличии нескольких полей с именем answer
Показать ещё 8 комментариев

Ещё вопросы

Сообщество Overcoder
Наверх
Меню