Блокировка serialVersionUID в Котлине

Я боролся все утро, чтобы заблокировать serialVersionUID в классе Kotlin. У меня есть BaseModel который расширен Project

 abstract class BaseModel<T>( var id: Int? = null, private val fileName: String, private val data: MutableList<T>, private val indices: MutableMap<Int, T> ) : Serializable { ... protected fun writeToDisk() { val oos = ObjectOutputStream(BufferedOutputStream(FileOutputStream(fetchFileName())) ) oos.writeObject(fetchData()); oos.close(); } } 

И класс проекта:

 class Project( var name: String = "", var repo: String = "" ) : BaseModel<Project>( data = Data.projects, indices = Data.projectsIndex, fileName = "data/projects.dat" ), Serializable { ... override fun toString(): String { return "Project: id=${id}, name=${name}, repo=${repo}" } } 

Каждый раз, когда я пишу на диск, а затем меняю что-нибудь в классе и пытаюсь прочитать его снова, я бы получил:

java.io.InvalidClassException: com.jvaas.bob.model.Project; локальный класс несовместим: stream classdesc serialVersionUID = 4156405178259085766, локальный класс serialVersionUID = 2024101567466310467

Я попытался добавить:

 private val serialVersionUID: Long = 1 

для всех классов без эффекта.

В некоторых примерах для StackOverflow использовался serialVersionUid который также не имел никакого эффекта (я считаю, что это почему-то нижний индекс последних двух букв по какой-то причине)

@JvmStatic здесь не работает, поскольку это не object , я пытался сделать его не-частным без успеха.

Вы можете определить serialVersionUID как константу в сопутствующем объекте:

 abstract class BaseModel<T> : Serializable { companion object { private const val serialVersionUID: Long = -1 } } 

Константы скомпилированы в поля, а поля компаньона хранятся как статические поля класса, содержащего спутник. Поэтому вы получаете то, что вам нужно – частное статическое поле serialVersionUID в вашем сериализуемом классе.

Решение было намного проще, чем я думал, использовать сопутствующий объект. Это теперь прекрасно сериализуется, и если я добавляю больше полей, он все равно сериализуется на диск и десериализуется, если я не изменю serialVersionUID

База:

 abstract class BaseModel<T>( var id: Int? = null, private val fileName: String, private val data: MutableList<T>, private val indices: MutableMap<Int, T> ) : Serializable { companion object { @JvmStatic private val serialVersionUID: Long = 1 } ... } 

Проект:

 class Project( var name: String = "", var repo: String = "" ) : BaseModel<Project>( data = Data.projects, indices = Data.projectsIndex, fileName = "data/projects.dat" ), Serializable { companion object { @JvmStatic private val serialVersionUID: Long = 1 } override fun toString(): String { return "Project: id=${id}, name=${name}, repo=${repo}" } } 
Intereting Posts
Обменный код между модульными испытаниями и контрольно-измерительными тестами при использовании котлина Как избежать метода класса фабрики kotlin по подтипу? предупреждение: файлы JAR Kotlin для запуска в пути к классам должны иметь одну и ту же версию Почему я не могу использовать @PublishedApi для typealias? Тест инструмента Android с помощью Espresso не работает: NoSuchMethodError get () в javax.inject.Provider Увеличивает ли Android Studio 3.0 информацию о параметрах запроса? Вкус продукта: найден дубликат класса Недвижимость в интерфейсе не может иметь поле подкладочный Что такое java-эквивалент функций функций Котлина? Как я могу определить, когда тип Kotlin будет сопоставлен с типом Java? Котлин связал вызываемые ссылки несоответствия Что означает «с» в Котлине? Принятие объявления о создании платформы при использовании интерфейса в kotlin Комната с кинжалом в Котлине: Дао имеет значение null, при введении в класс Kotlin для assertThat (foo, instanceOf (Bar.class))