
1. Kotlin Data Class 탄생 배경: POJO(Plain Old Java Object) 지옥에서 벗어나기
Java POJO
// Java: 20줄 코드로 User 하나 만들기
public class User {
private String name;
private int age;
public User(String name, int age) {
this.name = name;
this.age = age;
}
// getter/setter 8줄
public String getName() { return name; }
public void setName(String name) { this.name = name; }
public int getAge() { return age; }
public void setAge(int age) { this.age = age; }
@Override public boolean equals(Object o) { /* 30줄 */ }
@Override public int hashCode() { /* 15줄 */ }
@Override public String toString() { /* 10줄 */ }
}
실제 사용되는 것은 name, age 뿐
Kotlin Data Class
data class User(val name: String, val age: Int)
한 줄로 끝낼 수 있으며, equals, hashCode, toString, copy까지 지원
2. Data Class 실전 용도
2.1 API Response Model (Retrofit)
data class UserResponse(
val id: Long,
val name: String,
val email: String,
val profileImage: String?
)
data class PostResponse(
val id: Long,
val title: String,
val content: String,
val user: UserResponse,
val createdAt: String
)
// Retrofit에서 바로 사용!
@GET("posts")
suspend fun getPosts(): List<PostResponse>
2.2 RecyclerView Adapter 데이터
sealed class TodoItem {
data class Task(val id: Long, val title: String, var isDone: Boolean) : TodoItem()
data class SectionHeader(val title: String) : TodoItem()
}
// DiffUtil에서 자동 equals 작동!
override fun areContentsTheSame(old: TodoItem, new: TodoItem): Boolean {
return old == new // data class가 알아서 비교!
}
2.3 Room Entity + Repository
@Entity(tableName = "todos")
data class TodoEntity(
@PrimaryKey val id: Long,
val title: String,
val priority: Int,
val createdAt: Long
)
@Dao
interface TodoDao {
@Query("SELECT * FROM todos ORDER BY priority DESC")
fun getAllTodos(): Flow<List<TodoEntity>> // Flow도 data class와 완벽 호환!
}
2.4 Room Entity + Repository
data class UiState(
val isLoading: Boolean = false,
val data: List<User>? = null,
val error: String? = null
) {
val isSuccess get() = data != null && !isLoading && error == null
}
// ViewModel에서 사용
private val _uiState = MutableStateFlow(UiState())
val uiState: StateFlow<UiState> = _uiState.asStateFlow()
fun updateData(users: List<User>) {
_uiState.value = _uiState.value.copy(data = users) // copy() 마법!
}
핵심: Data class는 불변성(immutability) + 편의 메서드
3. Swift의 Struct와 Kotlin의 Data Class
3.1 비교 표
| 특징 | Swift Struct | Kotiln Data Class |
| 타입 | Value Type | Reference Type |
| 복사 | 자동 값 복사 | 명시적 copy() |
| 메모리 | Stack/Heap 혼합 | 항상 Heap |
| equals | 자동(내용) | 자동(내용) |
| toString | 자동 description | 자동 toString |
| Thread Safety | 완전 안전 | val 사용 권장 |
3.2 복사 동작 비교(가장 중요한 차이)
Kotlin
// Kotlin: 참조 타입 → copy() 명시 필요
data class User(val name: String, var age: Int)
val user1 = User("철수", 20)
val user2 = user1 // 같은 객체!
user2.age = 25
println(user1.age) // 25 (같이 바뀜!)
val user3 = user1.copy(age = 30) // 새 객체!
Swift
// Swift: 값 타입 → 자동 복사
struct User {
let name: String
var age: Int
}
var user1 = User(name: "철수", age: 20)
var user2 = user1 // 완전 복사!
user2.age = 25
print(user1.age) // 20 (안 바뀜!)
// 새 객체는 이렇게
var user3 = User(name: user1.name, age: 30)
3.3 상태 업데이트 활용 사례
Kotlin
// Kotlin - copy()로 불변 업데이트
data class Todo(val id: Long, val title: String, val isDone: Boolean)
val todo = Todo(1, "공부", false)
val updatedTodo = todo.copy(isDone = true) // 한 줄!
todos = todos.map { if (it.id == todo.id) updatedTodo else it }
Swift
// Swift - 직접 새로 생성
struct Todo: Identifiable {
let id: UUID
var title: String
var isDone: Bool
}
let todo = Todo(id: UUID(), title: "공부", isDone: false)
let updatedTodo = Todo(id: todo.id, title: todo.title, isDone: true)
todos = todos.map { $0.id == todo.id ? updatedTodo : $0 }
참고: Android Studio, Perflexity
'Android' 카테고리의 다른 글
| Android Activity Life Cycle(feat. iOS App Life Cycle) (0) | 2026.01.22 |
|---|