Kotlin中的data class——什么是数据类、语法及其特点

作者: IT Sectr 发布日期: 2026-06-20 阅读时间: 10 分钟

data class是Kotlin中一种特殊类型的类,专门用于存储数据。编译器根据primary constructor中指定的属性自动生成equals、hashCode、toString、copy和componentN方法。根据JetBrains(2026)的文档,与Java等效代码相比,data class可以将样板代码量减少50–70%,并且是Kotlin项目中value对象的基础。

要点

  • data — 在Kotlin中声明数据类的关键字
  • equals和hashCode — 基于primary constructor的所有属性自动生成
  • copy — 浅拷贝函数,可替换单个字段
  • componentN — 将data class解构为单独的变量
  • Primary constructor必须包含至少一个val或var参数

Kotlin中的data class是什么?

data class是一种Kotlin语法结构,自动为主要目的是存储数据的类生成标准方法。声明data class时,编译器基于primary constructor中的所有属性创建equals、hashCode、toString、copy和componentN的实现。

与Java中的普通类不同,开发人员需要使用IDE或Lombok等库手动编写getter、setter、equals、hashCode和toString,而Kotlin提供了内置机制。这不仅缩短了代码,还保证了一致性——自动方法始终与当前的属性结构相匹配。

根据JetBrains Kotlin调查(2025),data class在78%的Kotlin项目中使用,使其成为该语言最受欢迎的功能之一。它在具有DTO、API响应模型和MVVM状态对象的架构中特别受欢迎。

语法和主要功能

data class使用class前的data关键字声明。参与自动方法的所有属性都在primary constructor中指定。

kotlin
data class User(
    val id: Int,
    val name: String,
    val email: String
)

一行代码取代了Java中数十行样板代码。编译器为所有三个属性生成equals、hashCode、toString、copy和component1–component3。

primary constructor之外的属性

自动方法只包含primary constructor中的属性。如果在类体中声明属性,它不参与equals、hashCode、toString和copy。

kotlin
data class Product(
    val id: Int,
    val title: String
) {
    var cachedPrice: Double = 0.0
    // cachedPrice不包括在equals/hashCode/copy中
}

primary constructor的限制

data class的primary constructor必须包含至少一个参数。所有参数必须标记为val或var。不能对data class使用open、abstract、sealed或inner修饰符。

自动方法equals、hashCode和toString

equals和hashCode基于primary constructor中所有属性的值生成。如果两个data class实例的所有对应属性相等,则它们被视为相等。

用于值比较的equals

Java中,对象的默认比较是引用比较(==)。基于值的比较需要重写equals。Kotlin data class自动完成此操作,允许使用==进行结构比较。

kotlin
data class Address(
    val city: String,
    val street: String
)

val a1 = Address("Moscow", "Tverskaya")
val a2 = Address("Moscow", "Tverskaya")
println(a1 == a2)  // true

用于调试的toString

toString方法返回对象的可读表示形式,包含所有属性的名称和值。与Java(默认以十六进制格式显示hash代码)相比,这大大简化了日志记录和调试。

根据Kotlin文档(2026),data class的toString格式为:“User(id=1, name=John, email=john@example.com)”。从primary constructor中删除属性时,toString会自动更新——消除了不同步的风险。

copy函数和解构

copy — data class的关键功能之一。它创建对象的浅拷贝,并可以更改指定属性的值。

kotlin
data class Order(
    val id: Long,
    val status: String,
    val amount: Double
)

val order = Order(1L, "Pending", 299.99)
val updatedOrder = order.copy(status = "Confirmed")
// updatedOrder.id = 1L, amount = 299.99, status = “Confirmed”

copy在函数式风格和不可变性(immutability)架构中不可或缺。不是改变现有对象,而是创建具有修改字段的新副本,这使得代码在多线程场景中更具可预测性和安全性。

通过componentN解构

data class自动为每个属性按声明顺序生成component1、component2等函数。这允许将对象解构为变量。

kotlin
val user = User(1, "Alice", "alice@example.com")
val (id, name, email) = user
println("$id: $name ($email)")  // “1: Alice (alice@example.com)”

解构也适用于lambda和for-each循环,这使得data class便于处理集合。

限制和建议

第一个限制——data class不支持继承另一个data class。只能继承普通类或实现接口。

第二个——自动方法只包含primary constructor的属性。类体中的属性被忽略,如果忘记这一点可能导致equals不正确。

第三个——data class不能是open、abstract、sealed或inner。它始终是final。

第四个——对于data class内的集合,copy执行浅拷贝。修改拷贝集合中的元素将影响原始集合。

根据Kotlin最佳实践(2026),data class最适合DTO、API模型、value objects和状态对象。对于包含业务逻辑的组件,建议使用普通类。

常见问题

data class可以继承另一个data class吗?

不能,data class不能继承另一个data class。但它可以继承普通类或实现接口。

primary constructor中应该有多少个属性?

至少一个属性。最大数量没有限制,但解构最多生成到componentN。

类体中的属性是否包含在equals中?

不,自动方法只考虑primary constructor中的属性。类体中的属性不参与equals、hashCode、toString和copy。

可以手动重写自动方法吗?

可以,可以在data class体中重写equals、hashCode或toString。在这种情况下,编译器不会生成自己的实现。

data class与普通类有何不同?

data class自动生成equals、hashCode、toString、copy和componentN。普通类在没有手动实现的情况下不提供这些方法。

总结

  • data class — 用于存储数据的Kotlin语法结构,自动生成方法
  • equals和hashCode — 基于primary constructor属性的结构比较
  • toString — 用于调试和日志记录的对象可读表示
  • copy — 通过命名参数替换单个字段的浅拷贝
  • componentN — 将对象解构为变量以方便处理集合
  • 限制 — 默认为final、至少一个属性、无data->data继承
  • 应用 — DTO、API模型、value objects、MVVM中的状态

我们将开发一款交钥匙移动应用程序

IT Sectr自2017年以来为初创企业和企业打造iOS和Android应用程序。我们将为您提供咨询并提出最佳解决方案。

讨论项目

另请阅读