Skip to Content
Course content
Click on the "Edit" button in the top corner of the screen to edit your slide content.

If you've spent any time in Java or C#, you know the pain of "POJOs" or "DTOs." You'd create a simple class to hold some data, and then you'd have to spend twenty minutes generating getters, setters, equals(), hashCode(), and toString() just so the class behaved predictably. In Kotlin, we have data classes, and they effectively kill that boilerplate entirely.

Why not just use a regular class for this?

You can, but you'll be doing a lot of manual labor. A regular class in Kotlin focuses on behavior. A data class focuses on data. When you mark a class with the data keyword, Kotlin automatically generates the plumbing for you based on the properties defined in the primary constructor.

// Instead of 50 lines of boilerplate, you get this:
data class UserProfile(
    val id: UUID, 
    val username: String, 
    val email: String, 
    val bio: String
)

I always recommend using val (read-only) for data class properties. Data classes are at their best when they are immutable. If you need to change something, you don't mutate the object; you create a new version of it. I'll show you how to do that in a second.

What is Kotlin actually doing "under the hood"?

The magic is in the generated methods. The most immediate difference you'll notice is the toString() implementation. A regular class prints a memory address (like UserProfile@4f32b1), which is useless for debugging. A data class prints the actual content.

val user1 = UserProfile(UUID.randomUUID(), "kotlin_fan", "fan@example.com", "I love concise code")
val user2 = UserProfile(user1.id, "kotlin_fan", "fan@example.com", "I love concise code")

println(user1) 
// Output: UserProfile(id=..., username=kotlin_fan, email=fan@example.com, bio=I love concise code)

println(user1 == user2) 
// Output: true

Notice that user1 == user2 is true. In a regular class, this would be false because they are different objects in memory. But for a data class, Kotlin generates an equals() method that checks if the values inside the properties are the same. This is a lifesaver when you're comparing API responses or filtering lists.

How do I "update" a value if everything is a val?

Since we're leaning into immutability, you can't just do user.email = "new@email.com". Instead, Kotlin gives you the copy() method. This allows you to create a new instance of the class, changing only the specific properties you care about while keeping the rest exactly the same.

val updatedUser = user1.copy(email = "updated_fan@example.com")

println(updatedUser.username) // Still "kotlin_fan"
println(updatedUser.email)    // Now "updated_fan@example.com"

This pattern is incredibly powerful in large-scale apps. It prevents those nasty bugs where one part of your code accidentally changes an object that another part of your code is still using.

Are there any catches or restrictions?

A few. First, a data class must have at least one parameter in its primary constructor, and all those parameters must be marked as val or var. You can't have a data class with an empty constructor.

Also, data classes cannot be abstract, open, sealed, or inner. They are designed to be final, simple containers. If you find yourself needing complex inheritance hierarchies, a data class probably isn't the right tool for that specific part of your architecture.




📋 Practical Task

Building a Shopping Cart Item Manager

You are building a small e-commerce module. You need to handle products that can be added to a cart, and occasionally, the price of a product changes while it's in the cart, or the quantity is updated.

Your Task:

  • Create a data class named CartItem with the following properties: productId (Int), name (String), price (Double), and quantity (Int).
  • In your main function, create an instance of a CartItem (e.g., a "Mechanical Keyboard" at $120.00 with a quantity of 1).
  • The user decides to buy 3 of these keyboards instead of 1. Use the copy() method to create a new CartItem with the updated quantity.
  • The store applies a 10% discount to the price. Use the copy() method again to create another version of the item with the discounted price.
  • Print all three versions of the item to the console to verify that the toString() output correctly shows the changes at each step.
Rating
0 0

There are no comments for now.

to be the first to leave a comment.