Как сериализовать закрытый класс kotlin с открытым val, используя сериализацию kotlinx

import kotlinx.serialization.Serializable

@Serializable
sealed class Exercise(open val id: String) {

    @Serializable
    data class Theory(override val id: String) : Exercise(id)
}

В моем коде есть такой запечатанный класс, и компилятор говорит мне: Serializable class has duplicate serial name of property 'id', either in the class itself or its supertypes.

Есть ли способ открыть val в сериализуемом запечатанном классе, который правильно работает при его переопределении?


person Bohdan Yevtushenko    schedule 30.07.2020    source источник
comment
Вы пробовали: data class Theory(id: String):Exercise(id)?   -  person amanin    schedule 31.07.2020
comment
Я не могу этого сделать с классами данных (потому что конструктор должен иметь только параметры свойства (val / var)), но даже если я сделаю это с class Theory(id: String) : Exercise(id), у меня будет эта ошибка: This class is not serializable automatically because it has primary constructor parameters that are not properties   -  person Bohdan Yevtushenko    schedule 31.07.2020


Ответы (1)


Это Kotlin issue KT-38958. Кажется, это угловой случай Требования к свойствам конструктора.

Это можно решить, используя следующую реализацию:

import kotlinx.serialization.*
import kotlinx.serialization.json.Json

@Serializable
sealed class Exercise {
    abstract val id: String

    @Serializable
    data class Theory(override val id: String) : Exercise()
}

fun main() {
    val t1 = Exercise.Theory("t1")
    val t1Json = Json.encodeToString(t1)
    println(t1Json)
    println(Json.decodeFromString<Exercise.Theory>(t1Json).toString())
}

который выведет:

{"id":"t1"}
Theory(id=t1)

Подробнее см. Проектирование сериализуемой иерархии в Руководстве по сериализации Kotlin.

person Oliver O.    schedule 22.08.2020