Skip to content

Kotlin 1.3 호환성 가이드

Kotlin 언어 설계의 근본 원칙 중 하나는 _언어의 현대성 유지_와 _편안한 업데이트_입니다. 전자는 언어 발전을 저해하는 구조를 제거해야 한다고 말하며, 후자는 코드 마이그레이션이 가능한 한 원활하도록 이러한 제거 사항을 사전에 충분히 알려야 한다고 말합니다.

대부분의 언어 변경 사항은 업데이트 변경 로그 또는 컴파일러 경고와 같은 다른 채널을 통해 이미 발표되었지만, 이 문서는 Kotlin 1.2에서 Kotlin 1.3으로의 마이그레이션을 위한 완전한 참조를 제공하며 모든 변경 사항을 요약합니다.

기본 용어

이 문서에서는 몇 가지 종류의 호환성을 소개합니다:

  • 소스: 소스 호환되지 않는 변경은 (오류나 경고 없이) 잘 컴파일되던 코드가 더 이상 컴파일되지 않게 합니다.
  • 바이너리: 두 바이너리 아티팩트는 서로 교환해도 로딩 또는 링키지 오류가 발생하지 않는 경우 바이너리 호환된다고 합니다.
  • 동작: 동일한 프로그램이 변경 사항을 적용하기 전후에 다른 동작을 보이는 경우 동작 호환되지 않는다고 합니다.

이러한 정의는 순수 Kotlin에만 적용된다는 점을 기억하십시오. 다른 언어(예: Java) 관점에서 Kotlin 코드의 호환성은 이 문서의 범위를 벗어납니다.

호환되지 않는 변경 사항

<clinit> 호출에 대한 생성자 인수 평가 순서

이슈: KT-19532

구성 요소: Kotlin/JVM

호환되지 않는 변경 유형: 동작

요약: 클래스 초기화에 대한 평가 순서가 1.3에서 변경되었습니다.

사용 중단 주기:

  • <1.3: 이전 동작 (이슈에서 자세한 내용 확인)
  • = 1.3: 동작 변경됨, -Xnormalize-constructor-calls=disable 플래그를 사용하여 일시적으로 1.3 이전 동작으로 되돌릴 수 있습니다. 이 플래그에 대한 지원은 다음 주요 릴리스에서 제거될 예정입니다.

어노테이션 생성자 매개변수에 대한 getter 대상 어노테이션 누락

이슈: KT-25287

구성 요소: Kotlin/JVM

호환되지 않는 변경 유형: 동작

요약: 어노테이션 생성자 매개변수에 대한 getter 대상 어노테이션이 1.3에서 클래스 파일에 올바르게 기록됩니다.

사용 중단 주기:

  • <1.3: 어노테이션 생성자 매개변수에 대한 getter 대상 어노테이션이 적용되지 않음
  • =1.3: 어노테이션 생성자 매개변수에 대한 getter 대상 어노테이션이 올바르게 적용되어 생성된 코드에 기록됩니다.

클래스 생성자의 @get: 어노테이션에서 누락된 오류

이슈: KT-19628

구성 요소: 코어 언어

호환되지 않는 변경 유형: 소스

요약: getter 대상 어노테이션의 오류가 1.3에서 올바르게 보고됩니다.

사용 중단 주기:

  • <1.2: getter 대상 어노테이션의 컴파일 오류가 보고되지 않아, 잘못된 코드가 정상적으로 컴파일될 수 있었습니다.
  • 1.2.x: 도구에 의해서만 오류가 보고되었고, 컴파일러는 여전히 경고 없이 해당 코드를 컴파일했습니다.
  • =1.3: 컴파일러에 의해서도 오류가 보고되어, 오류가 있는 코드는 거부됩니다.

@NotNull로 어노테이션된 Java 타입에 대한 접근 시 null 허용 여부 단언

이슈: KT-20830

구성 요소: Kotlin/JVM

호환되지 않는 변경 유형: 동작

요약: null이 아님 어노테이션으로 어노테이션된 Java 타입에 대한 null 허용 여부 단언이 더 적극적으로 생성되어, null을 전달하는 코드가 더 빨리 실패하도록 합니다.

사용 중단 주기:

  • <1.3: 타입 추론이 포함될 때 컴파일러가 이러한 단언을 놓칠 수 있었고, 바이너리에 대한 컴파일 중 잠재적인 null 전파를 허용했습니다 (자세한 내용은 이슈 참조).
  • =1.3: 컴파일러가 누락된 단언을 생성합니다. 이로 인해 (잘못되게) null을 전달하던 코드가 더 빨리 실패할 수 있습니다. -XXLanguage:-StrictJavaNullabilityAssertions 플래그를 사용하여 일시적으로 1.3 이전 동작으로 되돌릴 수 있습니다. 이 플래그에 대한 지원은 다음 주요 릴리스에서 제거될 예정입니다.

enum 멤버에 대한 잘못된 스마트 캐스트

이슈: KT-20772

구성 요소: 코어 언어

호환되지 않는 변경 유형: 소스

요약: 특정 enum 항목의 멤버에 대한 스마트 캐스트는 해당 enum 항목에만 올바르게 적용됩니다.

사용 중단 주기:

  • <1.3: 특정 enum 항목의 멤버에 대한 스마트 캐스트가 다른 enum 항목의 동일한 멤버에 대해 잘못된 스마트 캐스트로 이어질 수 있었습니다.
  • =1.3: 스마트 캐스트는 특정 enum 항목의 멤버에만 올바르게 적용됩니다. -XXLanguage:-SoundSmartcastForEnumEntries 플래그는 일시적으로 이전 동작으로 되돌립니다. 이 플래그에 대한 지원은 다음 주요 릴리스에서 제거될 예정입니다.

getter에서 val 배킹 필드 재할당

이슈: KT-16681

구성 요소: 코어 언어

호환되지 않는 변경 유형: 소스

요약: val 속성의 getter에서 배킹 필드를 재할당하는 것이 이제 금지됩니다.

사용 중단 주기:

  • <1.2: Kotlin 컴파일러는 val의 getter에서 배킹 필드를 수정하는 것을 허용했습니다. 이는 Kotlin 시맨틱을 위반할 뿐만 아니라, final 필드를 재할당하는 잘못된 JVM 바이트코드를 생성했습니다.
  • 1.2.X: val의 배킹 필드를 재할당하는 코드에 대해 사용 중단 경고가 보고됩니다.
  • =1.3: 사용 중단 경고가 오류로 승격됩니다.

for-루프에서 반복되기 전 배열 캡처

이슈: KT-21354

구성 요소: Kotlin/JVM

호환되지 않는 변경 유형: 소스

요약: for-루프 범위의 표현식이 루프 본문에서 업데이트되는 지역 변수인 경우, 이 변경은 루프 실행에 영향을 미칩니다. 이는 범위, 문자 시퀀스, 컬렉션과 같은 다른 컨테이너를 반복하는 것과 일치하지 않습니다.

사용 중단 주기:

  • <1.2: 설명된 코드 패턴은 잘 컴파일되지만, 지역 변수 업데이트가 루프 실행에 영향을 미칩니다.
  • 1.2.X: for-루프의 범위 표현식이 루프 본문에서 할당되는 배열 타입의 지역 변수인 경우 사용 중단 경고가 보고됩니다.
  • 1.3: 이러한 경우 동작을 다른 컨테이너와 일관되도록 변경합니다.

enum 항목의 중첩 분류자

이슈: KT-16310

구성 요소: 코어 언어

호환되지 않는 변경 유형: 소스

요약: Kotlin 1.3부터 enum 항목 내의 중첩 분류자(클래스, 객체, 인터페이스, 어노테이션 클래스, enum 클래스)가 금지됩니다.

사용 중단 주기:

  • <1.2: enum 항목의 중첩 분류자는 잘 컴파일되지만, 런타임에 예외와 함께 실패할 수 있습니다.
  • 1.2.X: 중첩 분류자에 대해 사용 중단 경고가 보고됩니다.
  • =1.3: 사용 중단 경고가 오류로 승격됩니다.

copy를 오버라이딩하는 데이터 클래스

이슈: KT-19618

구성 요소: 코어 언어

호환되지 않는 변경 유형: 소스

요약: Kotlin 1.3부터 데이터 클래스가 copy()를 오버라이딩하는 것이 금지됩니다.

사용 중단 주기:

  • <1.2: copy()를 오버라이딩하는 데이터 클래스는 잘 컴파일되지만 런타임에 실패하거나 이상한 동작을 보일 수 있습니다.
  • 1.2.X: copy()를 오버라이딩하는 데이터 클래스에 대해 사용 중단 경고가 보고됩니다.
  • =1.3: 사용 중단 경고가 오류로 승격됩니다.

외부 클래스에서 제네릭 매개변수를 캡처하는 Throwable을 상속하는 내부 클래스

이슈: KT-17981

구성 요소: 코어 언어

호환되지 않는 변경 유형: 소스

요약: Kotlin 1.3부터 내부 클래스가 Throwable을 상속하는 것이 허용되지 않습니다.

사용 중단 주기:

  • <1.2: Throwable을 상속하는 내부 클래스는 잘 컴파일됩니다. 만약 이러한 내부 클래스가 제네릭 매개변수를 캡처하는 경우, 런타임에 실패하는 이상한 코드 패턴으로 이어질 수 있었습니다.
  • 1.2.X: Throwable을 상속하는 내부 클래스에 대해 사용 중단 경고가 보고됩니다.
  • =1.3: 사용 중단 경고가 오류로 승격됩니다.

동반 객체를 포함하는 복잡한 클래스 계층 구조에 대한 가시성 규칙

이슈: KT-21515, KT-25333

구성 요소: 코어 언어

호환되지 않는 변경 유형: 소스

요약: Kotlin 1.3부터 동반 객체와 중첩 분류자를 포함하는 복잡한 클래스 계층 구조에서 짧은 이름에 의한 가시성 규칙이 더 엄격해집니다.

사용 중단 주기:

  • <1.2: 이전 가시성 규칙 (자세한 내용은 이슈 참조)
  • 1.2.X: 더 이상 접근할 수 없는 짧은 이름에 대해 사용 중단 경고가 보고됩니다. 도구는 전체 이름을 추가하여 자동 마이그레이션을 제안합니다.
  • =1.3: 사용 중단 경고가 오류로 승격됩니다. 문제가 되는 코드는 전체 한정자 또는 명시적 import를 추가해야 합니다.

비상수 vararg 어노테이션 매개변수

이슈: KT-23153

구성 요소: 코어 언어

호환되지 않는 변경 유형: 소스

요약: Kotlin 1.3부터 비상수 값을 vararg 어노테이션 매개변수로 설정하는 것이 금지됩니다.

사용 중단 주기:

  • <1.2: 컴파일러는 vararg 어노테이션 매개변수에 비상수 값을 전달하는 것을 허용했지만, 바이트코드 생성 중 해당 값을 실제로 삭제하여 명확하지 않은 동작으로 이어졌습니다.
  • 1.2.X: 이러한 코드 패턴에 대해 사용 중단 경고가 보고됩니다.
  • =1.3: 사용 중단 경고가 오류로 승격됩니다.

지역 어노테이션 클래스

이슈: KT-23277

구성 요소: 코어 언어

호환되지 않는 변경 유형: 소스

요약: Kotlin 1.3부터 지역 어노테이션 클래스는 지원되지 않습니다.

사용 중단 주기:

  • <1.2: 컴파일러는 지역 어노테이션 클래스를 잘 컴파일했습니다.
  • 1.2.X: 지역 어노테이션 클래스에 대해 사용 중단 경고가 보고됩니다.
  • =1.3: 사용 중단 경고가 오류로 승격됩니다.

지역 위임 속성에 대한 스마트 캐스트

이슈: KT-22517

구성 요소: 코어 언어

호환되지 않는 변경 유형: 소스

요약: Kotlin 1.3부터 지역 위임 속성에 대한 스마트 캐스트가 허용되지 않습니다.

사용 중단 주기:

  • <1.2: 컴파일러는 지역 위임 속성을 스마트 캐스트하는 것을 허용했지만, 이는 잘못된 위임자의 경우 잘못된 스마트 캐스트로 이어질 수 있었습니다.
  • 1.2.X: 지역 위임 속성에 대한 스마트 캐스트는 사용 중단으로 보고됩니다 (컴파일러가 경고를 발행).
  • =1.3: 사용 중단 경고가 오류로 승격됩니다.

mod 연산자 컨벤션

이슈: KT-24197

구성 요소: 코어 언어

호환되지 않는 변경 유형: 소스

요약: Kotlin 1.3부터 mod 연산자의 선언과 그러한 선언으로 확인되는 호출이 금지됩니다.

사용 중단 주기:

  • 1.1.X, 1.2.X: operator mod 선언 및 해당 선언으로 확인되는 호출에 대해 경고를 보고합니다.
  • 1.3.X: 경고를 오류로 승격하지만, operator mod 선언으로 확인되는 것은 여전히 허용합니다.
  • 1.4.X: 더 이상 operator mod 호출을 확인하지 않습니다.

단일 요소를 이름 있는 vararg에 전달

이슈: KT-20588, KT-20589. 또한 KT-20171 참조.

구성 요소: 코어 언어

호환되지 않는 변경 유형: 소스

요약: Kotlin 1.3에서는 단일 요소를 vararg에 할당하는 것이 사용 중단되었으며, 연속적인 스프레드 및 배열 생성으로 대체되어야 합니다.

사용 중단 주기:

  • <1.2: 이름 있는 vararg에 하나의 값 요소를 할당하는 것은 잘 컴파일되며 배열에 단일 요소를 할당하는 것으로 취급되어, 배열을 vararg에 할당할 때 명확하지 않은 동작을 유발했습니다.
  • 1.2.X: 이러한 할당에 대해 사용 중단 경고가 보고되며, 사용자들은 연속적인 스프레드 및 배열 생성으로 전환할 것을 권장받습니다.
  • 1.3.X: 경고가 오류로 승격됩니다.
  • = 1.4: 단일 요소를 vararg에 할당하는 시맨틱을 변경하여, 배열 할당이 배열의 스프레드 할당과 동일하게 만듭니다.

대상 EXPRESSION을 가진 어노테이션의 보존

이슈: KT-13762

구성 요소: 코어 언어

호환되지 않는 변경 유형: 소스

요약: Kotlin 1.3부터 대상 EXPRESSION을 가진 어노테이션에는 SOURCE 보존만 허용됩니다.

사용 중단 주기:

  • <1.2: 대상 EXPRESSIONSOURCE 이외의 보존을 가진 어노테이션은 허용되었지만, 사용 시점에서 묵묵히 무시되었습니다.
  • 1.2.X: 이러한 어노테이션 선언에 대해 사용 중단 경고가 보고됩니다.
  • =1.3: 경고가 오류로 승격됩니다.

대상 PARAMETER를 가진 어노테이션은 매개변수 타입에 적용되어서는 안 됩니다.

이슈: KT-9580

구성 요소: 코어 언어

호환되지 않는 변경 유형: 소스

요약: Kotlin 1.3부터 대상 PARAMETER를 가진 어노테이션이 매개변수 타입에 적용될 때 잘못된 어노테이션 대상에 대한 오류가 올바르게 보고됩니다.

사용 중단 주기:

  • <1.2: 앞서 언급된 코드 패턴은 잘 컴파일되었습니다; 어노테이션은 묵묵히 무시되었고 바이트코드에 존재하지 않았습니다.
  • 1.2.X: 이러한 사용에 대해 사용 중단 경고가 보고됩니다.
  • =1.3: 경고가 오류로 승격됩니다.

Array.copyOfRange는 반환된 배열을 확장하는 대신 인덱스가 범위를 벗어날 때 예외를 발생시킵니다.

이슈: KT-19489

구성 요소: kotlin-stdlib (JVM)

호환되지 않는 변경 유형: 동작

요약: Kotlin 1.3부터 Array.copyOfRangetoIndex 인수(복사되는 범위의 배타적 끝을 나타냄)가 배열 크기보다 크지 않도록 보장하고, 만약 크다면 IllegalArgumentException을 발생시킵니다.

사용 중단 주기:

  • <1.3: Array.copyOfRange 호출에서 toIndex가 배열 크기보다 큰 경우, 범위 내 누락된 요소는 null로 채워져 Kotlin 타입 시스템의 건전성을 위반했습니다.
  • =1.3: toIndex가 배열 범위 내에 있는지 확인하고, 그렇지 않으면 예외를 발생시킵니다.

Int.MIN_VALUELong.MIN_VALUE 스텝을 가진 Int 및 Long 진행은 불법이며 인스턴스화가 허용되지 않습니다.

이슈: KT-17176

구성 요소: kotlin-stdlib (JVM)

호환되지 않는 변경 유형: 동작

요약: Kotlin 1.3부터 정수 진행(progression)의 스텝(step) 값이 해당 정수 타입(Long 또는 Int)의 최소 음수 값이 되는 것을 금지하여, IntProgression.fromClosedRange(0, 1, step = Int.MIN_VALUE) 호출 시 IllegalArgumentException을 발생시킵니다.

사용 중단 주기:

  • <1.3: Int.MIN_VALUE 스텝으로 IntProgression을 생성하는 것이 가능했으며, 이는 두 값 [0, -2147483648]을 산출하여 명확하지 않은 동작을 보였습니다.
  • =1.3: 스텝이 해당 정수 타입의 최소 음수 값인 경우 IllegalArgumentException을 발생시킵니다.

매우 긴 시퀀스 작업 시 인덱스 오버플로 검사

이슈: KT-16097

구성 요소: kotlin-stdlib (JVM)

호환되지 않는 변경 유형: 동작

요약: Kotlin 1.3부터 index, count 및 유사 메서드가 긴 시퀀스에 대해 오버플로되지 않도록 합니다. 영향을 받는 메서드의 전체 목록은 이슈를 참조하십시오.

사용 중단 주기:

  • <1.3: 매우 긴 시퀀스에서 이러한 메서드를 호출하면 정수 오버플로로 인해 음수 결과가 나올 수 있었습니다.
  • =1.3: 이러한 메서드에서 오버플로를 감지하고 즉시 예외를 발생시킵니다.

빈 매치 정규식을 통한 split 결과 플랫폼 간 통일

이슈: KT-21049

구성 요소: kotlin-stdlib (JVM)

호환되지 않는 변경 유형: 동작

요약: Kotlin 1.3부터 빈 매치 정규식을 통한 split 메서드의 동작을 모든 플랫폼에서 통일합니다.

사용 중단 주기:

  • <1.3: 설명된 호출의 동작은 JS, JRE 6, JRE 7과 JRE 8+를 비교할 때 달랐습니다.
  • =1.3: 플랫폼 전반에 걸쳐 동작을 통일합니다.

컴파일러 배포판에서 사용 중단된 아티팩트 중단

이슈: KT-23799

구성 요소: 기타

호환되지 않는 변경 유형: 바이너리

요약: Kotlin 1.3은 다음 사용 중단된 바이너리 아티팩트를 중단합니다:

  • kotlin-runtime: 대신 kotlin-stdlib 사용
  • kotlin-stdlib-jre7/8: 대신 kotlin-stdlib-jdk7/8 사용
  • 컴파일러 배포판의 kotlin-jslib: 대신 kotlin-stdlib-js 사용

사용 중단 주기:

  • 1.2.X: 해당 아티팩트는 사용 중단으로 표시되었으며, 컴파일러는 이 아티팩트 사용 시 경고를 보고했습니다.
  • =1.3: 해당 아티팩트는 중단됩니다.

stdlib의 어노테이션

이슈: KT-21784

구성 요소: kotlin-stdlib (JVM)

호환되지 않는 변경 유형: 바이너리

요약: Kotlin 1.3은 stdlib에서 org.jetbrains.annotations 패키지의 어노테이션을 제거하고 컴파일러와 함께 제공되는 별도의 아티팩트인 annotations-13.0.jarmutability-annotations-compat.jar로 이동합니다.

사용 중단 주기:

  • <1.3: 어노테이션이 stdlib 아티팩트와 함께 제공되었습니다.
  • =1.3: 어노테이션은 별도의 아티팩트로 제공됩니다.