在 Kotlin 中,数据类(Data Class) 是专门为存储数据而设计的类,通过 data
关键字声明。它会自动生成 常用方法(如 toString()
、equals()
、hashCode()
、copy()
),并支持析构声明,极大简化了数据模型的编写。以下是详细解析:
一、基本语法与特性
1. 定义数据类
kotlin
data class User(
val name: String,
val age: Int,
val email: String = "" // 带默认值的参数
)
2. 自动生成的方法
-
**
toString()
** 输出类名和所有属性的值:
User(name=Alice, age=30, [email protected])
-
**
equals()
与hashCode()
** 基于所有主构造函数属性判断对象相等性:
inikotlinCopy Code val user1 = User("Alice", 30) val user2 = User("Alice", 30) println(user1 == user2) // true
-
**
copy()
** 创建对象的浅拷贝,支持修改部分属性:
goval user3 = user1.copy(age = 31) // 仅修改 age
-
**
componentN()
** 按属性声明顺序生成
component1()
、component2()
等函数,支持析构:kotlinval (name, age, email) = user1 // 直接解构属性
二、使用场景
1. DTO(数据传输对象)
用于网络请求或数据库交互的模型:
kotlin
data class ApiResponse(
val code: Int,
val message: String,
val data: User?
)
2. 状态管理
表示 UI 或业务逻辑的状态:
kotlin
data class LoginState(
val isLoading: Boolean,
val error: String?,
val user: User?
)
3. 简化集合操作
结合 map
、filter
处理对象集合:
ini
val users = listOf(User("Alice", 30), User("Bob", 25))
val names = users.map { it.name } // ["Alice", "Bob"]
三、注意事项与限制
1. 主构造函数要求
- 必须至少有一个
val
或var
参数。 - 不能是
abstract
、open
、sealed
或inner
类。
2. 继承与实现
数据类可以继承其他类或实现接口:
kotlin
data class AdminUser(
val role: String,
name: String,
age: Int
) : User(name, age), Serializable
3. 手动重写方法
如需自定义行为,可显式重写生成的方法:
kotlin
data class CustomUser(val id: String, val name: String) {
override fun toString(): String {
return "#$id: $name"
}
}
4. 深拷贝问题
copy()
是浅拷贝,引用类型属性不会复制:
kotlin
data class Company(val name: String, val employees: MutableList<User>)
val company1 = Company("Tech", mutableListOf(User("Alice", 30)))
val company2 = company1.copy()
company2.employees.add(User("Bob", 25))
// company1.employees 也会包含 Bob(浅拷贝问题)
四、数据类 vs 普通类
特性 | 数据类 | 普通类 |
---|---|---|
toString() |
自动生成(显示属性值) | 默认输出类名和哈希值 |
equals() /hashCode |
基于所有主构造函数属性 | 基于对象引用 |
copy() |
自动生成 | 需手动实现 |
析构支持 | 自动生成 componentN() |
需手动实现 |
适用场景 | 纯数据载体 | 含复杂逻辑的类 |
五、与 JSON 解析库结合
数据类常用于反序列化 JSON 数据(需配合库如 Gson
、Moshi
或 kotlinx.serialization
):
less
// 使用 kotlinx.serialization
@Serializable
data class Post(
val id: Int,
val title: String,
val content: String
)
// 反序列化 JSON 字符串
val json = """{"id": 1, "title": "Hello", "content": "World"}"""
val post = Json.decodeFromString<Post>(json)
六、总结
数据类的核心优势:
- 代码简洁:自动生成常用方法,减少样板代码。
- 语义明确:明确表示类用于存储数据。
- 功能实用:支持析构、拷贝和集合操作。
适用场景:
- 需要频繁比较、复制或打印数据的类。
- 作为函数参数或返回值传递的轻量级对象。
- 与 JSON 等序列化/反序列化技术结合使用。