You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用ObjectOutputStream序列化Kotlin数据类时遇java.io.NotSerializableException

解决Kotlin数据类使用ObjectOutputStream序列化抛出NotSerializableException的问题

问题原因

你混淆了两种完全独立的序列化机制:

  • 给BaseElement标记的@Serializable是Kotlinx Serialization库的注解,仅适用于该框架的序列化流程。
  • ObjectOutputStream是Java原生序列化工具,要求被序列化的类必须实现java.io.Serializable接口,和Kotlinx的注解没有关联,因此抛出NotSerializableException。

解决方案一:适配Java原生序列化机制

让BaseElement实现java.io.Serializable接口即可,可同时保留Kotlinx的@Serializable(如果后续需要用到Kotlinx序列化):

import kotlinx.serialization.Serializable
import java.io.Serializable as JavaSerializable

@Serializable
data class BaseElement(var sentence: String) : JavaSerializable

或者仅实现Java的Serializable接口:

import java.io.Serializable

data class BaseElement(var sentence: String) : Serializable

修改后即可正常使用ObjectOutputStream.writeObject()完成序列化。

解决方案二:改用Kotlinx Serialization框架序列化

如果你更倾向于使用Kotlin官方推荐的序列化方案,放弃Java原生的ObjectOutputStream,改用Kotlinx Serialization的API:

示例1:序列化为JSON字符串

import kotlinx.serialization.encodeToString
import kotlinx.serialization.json.Json

class MainActivity : AppCompatActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)
        debug()
    }
    
    fun debug() {
        val obj = BaseElement("HELLO WORLD")
        try {
            // 序列化为JSON字符串
            val jsonStr = Json.encodeToString(obj)
            // 若需要字节数组,可转换为UTF-8字节
            val bytes = jsonStr.toByteArray(Charsets.UTF_8)
            Log.d("mydebug", "序列化成功:$jsonStr")
        } catch(e: Exception) {
            Log.d("mydebug", e.stackTraceToString())
        }
    }
}

示例2:序列化为二进制字节流(Protobuf格式)

import kotlinx.serialization.protobuf.ProtoBuf
import kotlinx.serialization.encodeToByteArray

class MainActivity : AppCompatActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)
        debug()
    }
    
    fun debug() {
        val obj = BaseElement("HELLO WORLD")
        try {
            // 序列化为Protobuf二进制字节数组
            val bytes = ProtoBuf.encodeToByteArray(obj)
            Log.d("mydebug", "二进制序列化成功,字节长度:${bytes.size}")
        } catch(e: Exception) {
            Log.d("mydebug", e.stackTraceToString())
        }
    }
}

方案对比

  • Java原生序列化:适合需要和Java代码交互的场景,依赖Serializable接口,序列化结果是二进制流,但存在版本兼容性差、性能一般等问题。
  • Kotlinx Serialization:Kotlin官方推荐,支持JSON、Protobuf等多种格式,更灵活,兼容性和性能更优,适合纯Kotlin或跨平台项目。

内容的提问来源于stack exchange,提问作者Vishal Mahavar

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.04 19:25:20