data class trong Kotlin — nó là gì, cú pháp và đặc điểm của lớp dữ liệu

Tác giả: IT Sectr Đã đăng: 2026-06-20 Thời gian đọc: 10 phút

data class trong Kotlin là một loại lớp đặc biệt được thiết kế riêng để lưu trữ dữ liệu. Trình biên dịch tự động tạo các phương thức equals, hashCode, toString, copy và componentN dựa trên các thuộc tính được chỉ định trong hàm tạo chính. Theo tài liệu JetBrains (2026), data class cho phép giảm lượng mã mẫu tới 50–70% so với các tương đương Java và là nền tảng cho các đối tượng giá trị trong các dự án Kotlin.

Những điểm chính

  • data — từ khóa để khai báo lớp dữ liệu trong Kotlin
  • equals và hashCode — được tạo tự động dựa trên tất cả thuộc tính của hàm tạo chính
  • copy — hàm sao chép nông với khả năng thay thế các trường riêng lẻ
  • componentN — phân rã data class thành các biến riêng biệt
  • Hàm tạo chính phải chứa ít nhất một tham số val hoặc var

Data class trong Kotlin là gì?

data class là một cấu trúc cú pháp của Kotlin tự động tạo các phương thức tiêu chuẩn cho các lớp có mục đích chính là lưu trữ dữ liệu. Khi khai báo data class, trình biên dịch tạo ra các triển khai của equals, hashCode, toString, copy và componentN dựa trên tất cả thuộc tính từ hàm tạo chính.

Không giống như các lớp thông thường trong Java, nơi nhà phát triển phải tự viết getter, setter, equals, hashCode và toString bằng IDE hoặc thư viện như Lombok, Kotlin cung cấp cơ chế tích hợp sẵn. Điều này không chỉ giảm mã mà còn đảm bảo tính nhất quán — các phương thức tự động luôn tương ứng với cấu trúc thuộc tính hiện tại.

Theo Khảo sát Kotlin của JetBrains (2025), data class được sử dụng trong 78% dự án Kotlin, khiến nó trở thành một trong những tính năng được yêu cầu nhất của ngôn ngữ. Nó đặc biệt phổ biến trong các kiến trúc có DTO, mô hình phản hồi API và đối tượng trạng thái trong MVVM.

Cú pháp và các tính năng cơ bản

data class được khai báo với từ khóa data trước class. Tất cả các thuộc tính tham gia vào các phương thức tự động được chỉ định trong hàm tạo chính.

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

Một dòng mã thay thế hàng chục dòng mã mẫu trong Java. Trình biên dịch tạo equals, hashCode, toString, copy và component1–component3 cho cả ba thuộc tính.

Thuộc tính bên ngoài hàm tạo chính

Các phương thức tự động chỉ bao gồm các thuộc tính từ hàm tạo chính. Nếu một thuộc tính được khai báo trong thân lớp, nó không tham gia vào equals, hashCode, toString và copy.

kotlin
data class Product(
    val id: Int,
    val title: String
) {
    var cachedPrice: Double = 0.0
    // cachedPrice is NOT included in equals/hashCode/copy
}

Hạn chế của hàm tạo chính

Hàm tạo chính của data class phải chứa ít nhất một tham số. Tất cả tham số phải được đánh dấu là val hoặc var. Không thể sử dụng các bổ từ open, abstract, sealed hoặc inner cho data class.

Các phương thức tự động equals, hashCode và toString

equals và hashCode được tạo dựa trên giá trị của tất cả thuộc tính từ hàm tạo chính. Hai phiên bản của data class được coi là bằng nhau nếu tất cả các thuộc tính tương ứng của chúng bằng nhau.

equals để so sánh giá trị

Trong Java, so sánh đối tượng mặc định là so sánh tham chiếu (==). So sánh theo giá trị yêu cầu ghi đè equals. Kotlin data class thực hiện điều này tự động, cho phép sử dụng == để so sánh cấu trúc.

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 để gỡ lỗi

Phương thức toString trả về biểu diễn có thể đọc được của đối tượng với tên và giá trị của tất cả thuộc tính. Điều này đơn giản hóa đáng kể việc ghi nhật ký và gỡ lỗi so với Java, nơi đầu ra mặc định hiển thị mã băm ở định dạng thập lục phân.

Theo Tài liệu Kotlin (2026), toString của data class có định dạng: “User(id=1, name=John, email=john@example.com)”. Khi xóa thuộc tính khỏi hàm tạo chính, toString tự động cập nhật — rủi ro mất đồng bộ được loại bỏ.

Hàm copy và phân rã

copy là một trong những tính năng chính của data class. Nó tạo một bản sao nông của đối tượng với khả năng thay đổi giá trị của các thuộc tính được chỉ định.

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 không thể thiếu trong phong cách hàm và các kiến trúc với tính bất biến. Thay vì thay đổi đối tượng hiện có, một bản sao mới được tạo với các trường đã sửa đổi, làm cho mã dễ dự đoán hơn và an toàn hơn trong các kịch bản đa luồng.

Phân rã qua componentN

data class tự động tạo các hàm component1, component2, v.v. cho mỗi thuộc tính theo thứ tự khai báo. Điều này cho phép phân rã đối tượng thành các biến.

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

Phân rã cũng hoạt động trong lambda và vòng lặp for-each, làm cho data class thuận tiện khi làm việc với bộ sưu tập.

Hạn chế và khuyến nghị

Hạn chế đầu tiên — data class không hỗ trợ kế thừa từ data class khác. Chỉ có thể kế thừa từ các lớp thông thường hoặc giao diện.

Thứ hai — các phương thức tự động chỉ bao gồm các thuộc tính của hàm tạo chính. Các thuộc tính trong thân lớp bị bỏ qua, điều này có thể dẫn đến equals không chính xác nếu bạn quên điều này.

Thứ ba — data class không thể là open, abstract, sealed hoặc inner. Nó luôn là final.

Thứ tư — đối với bộ sưu tập bên trong data class, copy thực hiện sao chép nông. Thay đổi các phần tử bên trong bộ sưu tập được sao chép sẽ ảnh hưởng đến bản gốc.

Theo Các phương pháp hay nhất của Kotlin (2026), data class là tối ưu cho DTO, mô hình API, đối tượng giá trị và đối tượng trạng thái. Đối với các thành phần có logic kinh doanh, nên sử dụng các lớp thông thường.

Câu hỏi thường gặp

Data class có thể kế thừa data class khác không?

Không, data class không thể kế thừa data class khác. Tuy nhiên, nó có thể kế thừa một lớp thông thường hoặc triển khai giao diện.

Hàm tạo chính phải có bao nhiêu thuộc tính?

Ít nhất một thuộc tính. Số lượng tối đa không bị giới hạn, nhưng componentN được tạo để phân rã.

Các thuộc tính từ thân lớp có ảnh hưởng đến equals không?

Không, các phương thức tự động chỉ xem xét các thuộc tính từ hàm tạo chính. Các thuộc tính từ thân lớp không tham gia vào equals, hashCode, toString và copy.

Tôi có thể ghi đè các phương thức tự động thủ công không?

Có, bạn có thể ghi đè equals, hashCode hoặc toString trong thân data class. Trong trường hợp này, trình biên dịch không tạo triển khai riêng của nó.

Data class khác với lớp thông thường như thế nào?

data class tự động tạo equals, hashCode, toString, copy và componentN. Lớp thông thường không cung cấp các phương thức này nếu không có triển khai thủ công.

Tổng kết

  • data class — cấu trúc cú pháp Kotlin để lưu trữ dữ liệu với các phương thức tự động tạo
  • equals và hashCode — so sánh cấu trúc dựa trên thuộc tính của hàm tạo chính
  • toString — biểu diễn đối tượng có thể đọc được để gỡ lỗi và ghi nhật ký
  • copy — sao chép nông với thay thế các trường riêng lẻ bằng đối số có tên
  • componentN — phân rã đối tượng thành biến để làm việc thuận tiện với bộ sưu tập
  • Hạn chế — mặc định là final, ít nhất một thuộc tính, không kế thừa data->data
  • Ứng dụng — DTO, mô hình API, đối tượng giá trị, trạng thái trong MVVM

Chúng tôi sẽ phát triển ứng dụng di động chìa khóa trao tay

IT Sectr tạo các ứng dụng iOS và Android cho các công ty khởi nghiệp và doanh nghiệp từ năm 2017. Chúng tôi sẽ tư vấn và đề xuất giải pháp tốt nhất cho bạn.

Thảo luận dự án

Đọc thêm