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

Android Kotlin:Data Class中JSON嵌套对象的声明与映射问题

解决Kotlin中API响应模型嵌套对象声明与映射问题

一、正确声明嵌套的Remote响应模型

先确保所有嵌套对象的数据类定义正确且可访问,规避拼写、作用域类的低级问题。

假设你的目标JSON结构如下:

{
  "id": "topic_1",
  "title": "基础语法",
  "assetsStreak": {
    "currentStreak": 7,
    "maxStreak": 14
  },
  "testing": {
    "totalQuestions": 20,
    "completed": 12
  }
}

1. 定义嵌套对象的顶层数据类

将嵌套对象的模型定义为顶层类(或与父模型同包/同文件,确保可访问):

// AssetStreak的Remote响应模型
data class AssetStreakRemoteResponse(
    val currentStreak: Int,
    val maxStreak: Int
)

// Testing的Remote响应模型
data class TestingRemoteResponse(
    val totalQuestions: Int,
    val completed: Int
)

2. 在父模型中引用嵌套类

在TopicsItemRemoteResponseModel中直接声明嵌套字段,注意类名拼写完全一致:

data class TopicsItemRemoteResponseModel(
    val id: String,
    val title: String,
    val assetsStreak: AssetStreakRemoteResponse?, // 可空性根据JSON实际情况调整
    val testing: TestingRemoteResponse?
)

如果仍出现unresolved reference错误,排查这几点:

  • 嵌套类的拼写是否和引用时完全匹配(大小写、单词拼写都要一致)
  • 嵌套类是否在同一包下,或是否已正确导入(比如import com.yourpackage.AssetStreakRemoteResponse)
  • 不要将嵌套类定义为父类的private内部类,除非你明确需要内部类作用域

二、Remote模型到Domain模型的映射

Domain层模型要与Remote层解耦,只保留业务所需字段。

1. 定义Domain层模型

// Domain层的AssetStreak
data class AssetStreak(
    val currentStreak: Int,
    val maxStreak: Int
)

// Domain层的Testing
data class Testing(
    val totalCompleted: Int,
    val totalQuestions: Int
)

// Domain层的TopicsItem
data class TopicsItem(
    val id: String,
    val title: String,
    val streak: AssetStreak?,
    val testProgress: Testing?
)

2. 编写映射扩展函数

用Kotlin扩展函数实现Remote到Domain的转换,简洁直观:

// Remote的AssetStreak转Domain
fun AssetStreakRemoteResponse.toDomain(): AssetStreak {
    return AssetStreak(
        currentStreak = this.currentStreak,
        maxStreak = this.maxStreak
    )
}

// Remote的Testing转Domain
fun TestingRemoteResponse.toDomain(): Testing {
    return Testing(
        totalCompleted = this.completed,
        totalQuestions = this.totalQuestions
    )
}

// Remote的TopicsItem转Domain
fun TopicsItemRemoteResponseModel.toDomain(): TopicsItem {
    return TopicsItem(
        id = this.id,
        title = this.title,
        streak = this.assetsStreak?.toDomain(),
        testProgress = this.testing?.toDomain()
    )
}

3. 使用映射

在Repository或数据处理层调用转换逻辑:

// 假设从API获取到Remote模型实例
val remoteModel: TopicsItemRemoteResponseModel = apiService.getTopics()
val domainModel: TopicsItem = remoteModel.toDomain()

额外注意事项

  • 如果使用Retrofit/Gson等序列化库,确保嵌套类的字段与JSON键名匹配,或用@SerializedName指定映射关系(比如JSON键为assets_streak,则字段需加@SerializedName("assets_streak"))
  • 若JSON中嵌套对象可能为null,Remote模型的字段要声明为可空类型(?),避免序列化崩溃

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.24 12:33:19