KMM中如何实现JSON字符串转Domain对象并避免重复模板代码
KMM 跨平台 Domain 类 JSON 反序列化通用方案
你遇到的核心限制来自两个Kotlin/KMM特性:
- 接口的伴生对象无法被子类继承,所以不能直接在Domain接口定义全局静态方法给所有实现类调用
- 带
inline+reified关键字的方法不会被暴露到KMM的Native(iOS)侧,所以泛型推断的简化写法只能在Android/Kotlin环境用
以下是按推荐度排序的实现方案:
方案1:KSP 编译期自动生成代码(首选,零重复模板)
自定义KSP注解处理器,编译期扫描所有实现了Domain接口且标记了@Serializable的类,自动为其生成伴生对象的fromJSON方法,完全不需要手动编写重复代码。
实现逻辑:
- 定义基础标记接口
interface Domain
- 编写KSP处理器,匹配所有
Domain实现类,自动向其伴生对象注入以下代码:
fun fromJSON(json: String): [当前类名] = Json.decodeFromString(json)
- 编译后即可直接调用
User.fromJSON("{a:3, b:4}"),iOS侧可以正常识别该方法。
方案2:全局跨平台解析工具类(次选,无额外依赖)
如果不想引入KSP依赖,可以封装统一的解析工具类,分别适配双端调用:
import kotlinx.serialization.KSerializer import kotlinx.serialization.json.Json import kotlin.reflect.KClass object DomainJsonParser { // 对外暴露给iOS侧调用的非inline版本,传类对象即可 fun <T: Domain> fromJson(json: String, clazz: KClass<T>): T { return Json.decodeFromString(clazz.serializer(), json) } // 给Android/Kotlin侧用的inline简化版本,支持泛型推断 inline fun <reified T: Domain> fromJson(json: String): T { return fromJson(json, T::class) } }
调用示例:
- Android/Kotlin 侧:
val user = DomainJsonParser.fromJson<User>("{a:3, b:4}") - iOS 侧:
val user = DomainJsonParser.fromJson("{a:3, b:4}", User::class)
方案3:伴生对象扩展函数(仅Kotlin侧简化用)
如果不需要在iOS侧调用简化写法,可以直接给Domain的伴生对象加扩展函数,Kotlin侧直接调用即可:
inline fun <reified T: Domain> Domain.Companion.fromJson(json: String): T { return Json.decodeFromString(json) }
调用方式和你之前的写法一致:val user = Domain.fromJson<User>("{a:3, b:4}")
内容的提问来源于stack exchange,提问作者aepryus
相关产品推荐
相关产品推荐

