I’m trying to get a hello-world of serialization working after seeing it being ready in 1.4 (yay!)
I’ve got a class
class SimpleCache<K : Serializable, V : Serializable> {
private val cache: MutableMap<K, V> = ConcurrentHashMap()
fun persist() {
ObjectOutputStream(cacheFile.outputStream()).use {
it.writeObject(cache)
}
}
}
But all of the Kotlin Serialization guide uses Annotations, not implementations of the java.io.Serializable interface. It even says “Serializable classes have to be explicitly marked.”
I’d like to change the above persist() example to store the map in a Cbor.encodeToByteArray(cache) then write the bytes to a file. Is there an easy way to move over? I think I assumed implementing the java.io.Serializable type params would do the trick, or that I could somehow indicate that the type params were @Serializable.
Kotlinx.serialization does not use any Java interface as it’s multiplatform, you will have implement a “bridge” between kotlinx.serialization process and Java Serializable interface
Java Serialization and kotlinx.serialization are quite different. Javas serialization is specific to JVM and is designed to store java objects, complete with type information and everything. It relies on support from the JVM itself.
kotlinx.serialization, however, is designed to be a multiplatform tool for mapping kotlin objects to and from generic formats, primarily JSON. In order to work on native platforms, which has very limited reflection support, it relies on serializers being generated at compile time for each class that needs to be serialized. This is where @Serializable comes into the picture. It is not used for anything interesting at runtime. It is used by the compiler plugin, which generates serializers for classes annotated with @Serializable. There are also ways to define serializers for third-party classes not annotated with @Serializable, which is described in the manual, but they still require you to define serializers for each class at compile time.
Is there any way to tell the compiler “Hey you! For any class in this package that implements java.io.Serializable, please consider it tagged @Serializable. Thanks!”
Otherwise, I’m not sure if it is possible to do in a clean generic way what I’m trying to do. I don’t know how to enforce type constraints that require the class types to be tagged “@Serializable” the same that I can require it to be implementing java.io.Serializable.
I see what you want, unfortunately I had the same issue and never found a workaround, I ended up sacrificing compiler safety and doing reflection based detection using serializerOrNull() on the KClass instance.
I think i’m going to open an issue on their github (if I don’t find one open already).
I’m not sure if they would accept it though because their philosophy is to hide (using the BINARY retention policy) any reference to the serialization annotation to keep the objects “clean” and I don’t know if adding an interface automatically fits in here.
I think the simplest way I can describe it is “In a function that uses generics, is it possible to restrict to Kotlin @Serializable types being passed in?”