Ошибка сериализации Gson с val в котлине - PullRequest
0 голосов
/ 16 ноября 2018

Я использую 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 совпадает с именем переменной?

1 Ответ

0 голосов
/ 16 ноября 2018

Попробуйте переименовать параметр 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, поэтому при сериализации свойств возникает конфликт.

...