안드로이드 코틀린 언어 학습 노트 목차

자바 interop·코틀린 관용구 — 두 언어가 만나는 곳

안드로이드 코드베이스는 코틀린과 자바가 섞여 있는 경우가 많다 — 오래된 자바 코드, 자바로 짠 라이브러리, 그리고 새 코틀린 코드. 코틀린은 자바와 100% 상호운용되지만, 경계에서 주의할 점이 있다. 이 장은 interop 실무와, 자주 쓰는 *코틀린 관용구(Effective Kotlin 요점)*를 모은다 — andkt 언어편의 마무리다. (출처: Kotlin Docs — Java interop / Calling Kotlin from Java / Effective Kotlin.)

코틀린에서 자바 호출 — 플랫폼 타입을 조심

자바 메서드는 null 정보가 없어 코틀린에서 *플랫폼 타입(String!)*으로 보인다([02 널 안전]). 자바가 null을 줄 수 있으면 런타임 NPE 위험이니, 경계에서 명시 타입으로 받아 null 처리한다.

val name: String? = javaUser.getName()   // 자바 반환을 String?로 명시 → 강제 null 처리

자바의 getter/setter는 코틀린에서 프로퍼티처럼 보인다 — javaUser.name(getName 호출). 자바 라이브러리에 @Nullable/@NonNull이 달려 있으면 코틀린이 정확한 nullability로 본다.

자바에서 코틀린 호출 — @Jvm 어노테이션

반대로 자바에서 코틀린을 쓸 때 매끄럽게 하려면 어노테이션을 단다.

class Util {
    companion object {
        @JvmStatic fun parse(s: String) = ...   // 자바에서 Util.parse() (없으면 Util.Companion.parse())
    }
}

@JvmOverloads                                    // 기본 인자 → 자바용 오버로드 생성
fun greet(name: String, polite: Boolean = true) { }

const val MAX = 100                              // 자바에서 상수처럼 (@JvmField도)
  • @JvmStatic — companion 멤버를 진짜 정적으로(자바 호출 간결).
  • @JvmOverloads기본 인자를 자바용 오버로드 메서드로 펼침(자바엔 기본 인자가 없으므로).
  • @JvmField — 프로퍼티를 필드로 노출(getter 우회).
  • @JvmName — 시그니처 충돌 시 자바에서 보일 이름 변경.
  • @Throws — 코틀린엔 checked 예외가 없으니, 자바에 throws 선언이 필요하면 명시.

SAM 변환 — 함수형 인터페이스를 람다로

자바의 *단일 추상 메서드 인터페이스(SAM)*는 코틀린에서 람다로 넘길 수 있다.

button.setOnClickListener { v -> onClick() }    // OnClickListener(SAM)를 람다로
executor.execute { doWork() }                    // Runnable을 람다로

코틀린 자체 인터페이스를 SAM처럼 쓰려면 fun interface로 선언한다.

자주 쓰는 코틀린 관용구

실무에서 반복되는 Effective Kotlin 식 패턴들:

// 1) 인자 검증 — require/check (IllegalArgument/IllegalState)
fun setAge(age: Int) {
    require(age >= 0) { "나이는 음수 불가: $age" }   // 아니면 IllegalArgumentException
}

// 2) 리소스 자동 해제 — use (자바 try-with-resources)
file.bufferedReader().use { reader ->
    reader.readText()                              // 블록 끝나면 자동 close (예외 나도)
}

// 3) 안전한 결과 래핑 — runCatching
val result = runCatching { api.load() }
    .getOrElse { emptyList() }                     // 예외 시 기본값

// 4) when/if를 식으로 — 분기마다 값 반환 (망라성)
val label = when (state) { ... }

기타 관용구 — 불변 우선(val·읽기 전용 컬렉션), 명명 인자로 가독성, 데이터는 data class, 상태는 sealed, !! 최소화, 확장 함수로 유틸. 이것들이 코틀린다운(idiomatic) 코드다.

interop 시 흔한 함정

다이어그램 로딩 중…
  • 코틀린 top-level 함수는 자바에서 파일명Kt.함수()로 보인다(@file:JvmName으로 변경).
  • 코틀린 기본 인자는 자바에서 안 보인다(@JvmOverloads 필요).
  • 코틀린 Unit은 자바 void, Nothing은 특수 처리.

정리 — 경계를 알면 섞어 쓸 수 있다

코틀린-자바 interop의 핵심 — 자바에서 올 땐 플랫폼 타입(NPE)을 명시 타입으로 방어, 자바로 노출할 땐 @JvmStatic/@JvmOverloads/@JvmField로 매끄럽게, SAM은 람다로. 그리고 require/check·use·runCatching·불변·명명 인자 같은 관용구가 코틀린다운 코드를 만든다. 이제 언어를 갖췄으니, [andarch] 아키텍처와 [andsys] 프레임워크로 넘어간다.

한 줄 요약 — 자바→코틀린: 플랫폼 타입 명시로 NPE 방어, getter는 프로퍼티. 코틀린→자바: @JvmStatic·@JvmOverloads·@JvmField·@JvmName·@Throws. SAM은 람다(fun interface). 관용구: require/check·use·runCatching·불변·명명 인자.

(출처: Kotlin — Java Interop / Calling Kotlin from Java / Effective Kotlin / Android Kotlin-Java interop guide.)

DSL·연산자 오버로딩·중위 함수