锁定Kotlin中的serialVersionUID
我一整个早上都在serialVersionUID
地锁定一个Kotlin类的serialVersionUID
。 我有一个由Project
扩展的BaseModel
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}" } }
每次我给Disk写信,然后改变课堂上的任何内容,然后尝试再读一遍,我就会得到:
java.io.InvalidClassException:com.jvaas.bob.model.Project; 本地类不兼容:流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}" } }