
어제 저녁 7시, 사이드 프로젝트 build.gradle.kts 에 -Xcontext-parameters 한 줄 박고 IntelliJ 인스펙션 돌렸더니, 함수 레벨 context receiver 가 한 시간 만에 다 변환되더라구요.
JetBrains 가 5월 13일에 코틀린(Kotlin) 2.4.0-RC 를 풀었습니다. context parameters, explicit backing fields, kotlin.uuid.Uuid API 가 Stable 로 승격됐어요. 9년 묵은 YouTrack 이슈(KT-19627) 였던 name-based destructuring 은 이번 RC 에 새로 들어온 건 아니고, 사실 2.3.20 에서 이미 실험 단계로 들어왔고 2.5.0 Stable 을 앞두고 있는 상황이에요. 한 시간 적용해보면서 짚어둘 자리가 의외로 많아서 정리해둡니다.
Kotlin 2.4.0-RC context parameters Stable 승격, 한 시간 변환기
build.gradle.kts 에 -Xcontext-parameters 플래그를 추가해야 시작이 됩니다. Stable 로 풀렸어도 기본 활성화는 아직 아닌 상황으로 보입니다.
기존 context receivers 와 가장 큰 차이는 호출 방식입니다. 예전엔 스코프에 멤버가 암묵적으로 주입돼서 bar() 처럼 그냥 부르면 됐는데요, 2.4.0 부터는 호출 자체가 막힌 건 아니지만 모호성이 생길 때 contextObject.bar() 처럼 컨텍스트를 명시적으로 참조해 풀어줄 수 있게 바뀌었습니다 (자세한 동작은 KEEP-0367 참고). 의존성 출처가 코드만 봐도 보이게 손쓸 여지가 생긴 셈이지요.
마이그레이션은 인텔리J(IntelliJ) 인스펙션 "Migrate from context receivers to context parameters" 가 거의 다 해줍니다. 다만 클래스 스코프에 적용된 context receiver 는 자동 변환이 안 되더라구요. 제 코드에서도 클래스 4개는 결국 손으로 풀었습니다.
DI 컨테이너 대체로 쓰는 건 안티패턴이라고 봅니다. Logger, CoroutineScope, 트랜잭션 핸들처럼 스코프 안에서 "주변 환경"으로 흐르는 의존성에만 한정해서 쓰시는 게 좋겠어요. 의존성 그래프 추적이 어려워지는 순간 코드 리뷰 비용이 급증하는 경우가 많거든요.

name-based destructuring 로드맵 함정
이건 진짜 조심해야 할 자리예요. 앞서 적었듯 실험 도입 자체는 2.3.20 에 이미 끝났고, 2.5.0 에서 Stable 로 올라올 예정입니다. 문법 자체는 이렇게 생겼습니다.
data class Person(val name: String, val age: Int)
// 기존 — 위치 기반 분해 (선언 순서대로 매칭)
val (a, b) = person
// 새 문법 — 이름 기반 분해 (순서 무관, 프로퍼티 이름으로 매칭)
val (val name, val age) = person
활성화는 -Xname-based-destructuring=only-syntax 플래그가 필요한 실험 기능입니다. 여기까지만 보면 "그냥 안 쓰면 되네" 싶은데, 보면 얘기가 달라져요.
JetBrains가 공개한 로드맵에 따르면, 2.5.0에서 name-based 문법이 Stable로 풀린 뒤, 충분한 마이그레이션 기간을 두고 "distant future"에 괄호 ()의 기본 동작이 이름 기반으로 바뀐다고 합니다. 정확한 버전 시점은 아직 발표되지 않았지만, 2.5.0 Stable 이후 몇 차례 마이너 릴리즈를 거친 뒤가 될 가능성이 큽니다. 현재 위치 기반으로 작성된 val (a, b) = person 코드가, 그때부터는 이름이 안 맞으면 컴파일 에러가 나거나 다른 프로퍼티를 집어올 수 있다는 얘기입니다. 위치 기반은 향후 대괄호 [] 문법으로 분리될 예정이라고 해요.
감이 안 오신다면, data class 필드 순서를 한 번이라도 바꿔본 적이 있는 프로젝트는 전부 잠재적 폭탄을 안고 있다고 보시면 됩니다. 9년치 코틀린 코드베이스가 영향권에 들어오는 변경이에요.
개인적으로는 지금 시점에 팀 컨벤션으로 (val name, val age) 명시 형태만 쓰도록 못 박는 걸 추천드리고 싶네요. 전환기에 디프(diff) 가 폭증하는 걸 막을 수 있어요.

Explicit Backing Fields 로 ViewModel 보일러플레이트 줄이기
_list / list 쌍, 안드로이드(Android) 개발자라면 매일 보는 그 패턴 맞아요.
// 기존 — private 백업 + public 노출
private val _items = mutableListOf<Item>()
val items: List<Item> get() = _items
2.4.0 Stable 부터는 이렇게 쓸 수 있게 되었습니다.
// 2.4.0 — explicit backing field
val items: List<Item>
field: MutableList<Item> = mutableListOf()
외부 노출은 List, 내부 조작은 MutableList 라는 의도가 한 곳에 모입니다. 이름 두 개 짓느라 _items 같은 언더스코어 컨벤션을 끌고 다닐 필요도 없어졌네요. 줄 수 자체보다 "이 프로퍼티는 read-only 인터페이스를 쓰는 mutable 컬렉션이다" 라는 설계 의도가 코드에 박힌다는 점이 좋더라구요.
Kotlin 2.4.0-RC 적용 시 확인할 4가지 (KSP·Linter·시점·Maven)
RC 단계라 프로덕션 적용은 권장하지 않습니다. 다만 feature 브랜치에 미리 깔아두고 팀 내 학습용으로 돌리기엔 지금이 좋은 타이밍이라고 봅니다.
1. KSP 버전 정합성
Room, Hilt 같은 KSP 기반 라이브러리를 쓰면 Cannot find symbol 에러가 터질 수 있어요. KSP 도 코틀린 릴리즈에 맞물려 따라 올라오기 때문에, 릴리즈 페이지에 매칭되는 빌드를 찾아서 맞춰주셔야 합니다. 제 프로젝트에서도 첫 빌드는 여기서 죽었습니다.
2. Linter 호환성
ktlint 일부 버전이 context parameters 같은 새 문법을 인식 못 해서 포맷 오류를 내는 경우가 있습니다. CI 게이트로 ktlint 를 걸어두셨다면 해당 룰만 일시적으로 비활성화하시는 게 안전해요.
3. 실험 시점 — Stable 출시 전이 학습 골든타임
Stable 이 풀리고 나면 블로그·StackOverflow 답변이 쏟아져서 정보가 흔해집니다. 지금 RC 단계에서 발 한 번 담가보면 정식 출시 후에 팀에서 "이거 어떻게 마이그레이션해?" 라는 질문이 나왔을 때 답이 손에 들려있게 됩니다. 학습 일정에 Task Budgets 한 칸 잡아두는 정도면 충분해요.
4. Maven jvmTarget 자동화
최근 버전 기준으로 kotlin-maven-plugin 이 프로젝트의 java.toolchain.languageVersion 에 맞춰 jvmTarget 을 자동 설정하게 바뀌었습니다. 수동으로 박아뒀던 <jvmTarget>17</jvmTarget> 같은 줄은 이번 기회에 빼셔도 됩니다.

context receivers 미리 도입한 4군데, 어제 한 시간의 기록
작년 가을에 context receivers 가 빠진다는 소문이 돌 때, 사이드 프로젝트에 굳이 미리 도입해뒀던 자리가 4군데 있었어요. 어제 변환 돌리는데 그 4군데 중 3개가 함수 레벨이라 클릭 한 번에 끝났고, 나머지 1개가 클래스 스코프라 30분을 끌었습니다. 인스펙션이 못 잡는 클래스 케이스 하나가 결국 30분이라는 얘기예요. 자동화 도구가 다 해주는 건 아니라서, 결국 마지막 30분은 HITL — 사람이 들어가서 보정해야 하는 구간이더라구요.
다음 글에선 context parameters 위에서 CoroutineScope 와 Logger 를 같이 흘리는 패턴 — DI 컨테이너 안 건드리고 테스트 코드만으로 갈아끼우는 방식을 좀 더 깊이 파볼 생각이에요. distant future의 destructuring 폭탄을 막을 코드 컨벤션 PR 도 그 글에 같이 묶어 올릴 계획입니다.
'Android 개발 > Kotlin' 카테고리의 다른 글
| Kotlin 2.4 RC context parameters로 LoggerContext 6인자 날린 후기 (0) | 2026.06.10 |
|---|---|
| IntelliJ IDEA 2026.1 코루틴 인스펙션, 6년차 코드를 17번 찌르다 (0) | 2026.06.08 |
| KMP 2.3 production-ready 선언, 6년차 안드러가 본 진짜 도입선 (0) | 2026.06.02 |
| Kotlin 2.3.20 name-based destructuring, 안드 코드 7곳에 끼워본 일주일 (0) | 2026.06.01 |
| 코루틴 처음 만났을 때 가장 헷갈렸던 것들 (0) | 2026.05.04 |