Kotlin 1.3.x 互換性ガイド
『言語をモダンに保つ』および『スムーズなアップデート』は、Kotlin 言語設計における基本的な原則です。前者は、言語の進化を妨げる構文は削除されるべきであることを示し、後者は、コードの移行を可能な限りスムーズにするために、その削除について事前に十分に周知されるべきであることを示しています。
言語変更の多くは、アップデートの変更ログやコンパイラの警告など、他のチャネルを通じてすでに発表されていますが、このドキュメントではそれらをすべてまとめ、Kotlin 1.2 から Kotlin 1.3 への移行に関する完全なリファレンスを提供します。
基本用語
このドキュメントでは、いくつかの種類の互換性を紹介します:
- ソース: ソース互換性のない(source-incompatible)変更により、以前は正常にコンパイルできていた(エラーや警告なし)コードがコンパイルできなくなります。
- バイナリ: 2つのバイナリアーティファクトを入れ替えてもロードエラーやリンケージエラーが発生しない場合、それらはバイナリ互換(binary-compatible)であると言われます。
- 振る舞い: 変更の適用前後で同一のプログラムが異なる挙動を示す場合、その変更は振る舞い互換性のない(behavioral-incompatible)変更であると言われます。
これらの定義は純粋な Kotlin に対してのみ適用されることに注意してください。他の言語(Java など)から見た Kotlin コードの互換性は、このドキュメントの範囲外です。
互換性のない変更
<clinit> 呼び出しに関するコンストラクタ引数の評価順序
Issue: KT-19532
コンポーネント: Kotlin/JVM
互換性のない変更の種類: 振る舞い
概要: クラスの初期化に関する評価順序が 1.3 で変更されました。
非推奨サイクル:
- < 1.3: 旧来の動作(詳細は Issue を参照)
= 1.3: 動作が変更されました。
-Xnormalize-constructor-calls=disableを使用して、一時的に 1.3 以前の動作に戻すことができます。このフラグのサポートは、次のメジャーリリースで削除される予定です。
アノテーションのコンストラクタパラメータにおける getter をターゲットとしたアノテーションの欠落
Issue: KT-25287
コンポーネント: Kotlin/JVM
互換性のない変更の種類: 振る舞い
概要: アノテーションのコンストラクタパラメータにおける getter ターゲットのアノテーションが、1.3 ではクラスファイルに正しく書き込まれるようになります。
非推奨サイクル:
- < 1.3: アノテーションのコンストラクタパラメータにおける getter ターゲットのアノテーションが適用されませんでした。
= 1.3: アノテーションのコンストラクタパラメータにおける getter ターゲットのアノテーションが正しく適用され、生成されたコードに書き込まれます。
クラスコンストラクタの @get: アノテーションにおけるエラー報告の欠落
Issue: KT-19628
コンポーネント: コア言語
互換性のない変更の種類: ソース
概要: getter ターゲットのアノテーションにおけるエラーが、1.3 では正しく報告されるようになります。
非推奨サイクル:
- < 1.2: getter ターゲットのアノテーションにおけるコンパイルエラーが報告されず、不正なコードが正常にコンパイルされていました。
- 1.2.x: ツールによってのみエラーが報告され、コンパイラは依然として警告なしでそのようなコードをコンパイルします。
= 1.3: コンパイラでもエラーが報告されるようになり、誤ったコードは拒否されます。
@NotNull が付与された Java 型へのアクセスにおける Nullability アサーション
Issue: KT-20830
コンポーネント: Kotlin/JVM
互換性のない変更の種類: 振る舞い
概要: not-null アノテーションが付与された Java 型に対する Nullability アサーションがより積極的に生成されるようになり、そこに
nullを渡すコードはより早い段階で失敗するようになります。非推奨サイクル:
- < 1.3: 型推論が関与する場合にコンパイラがこのようなアサーションを見逃すことがあり、バイナリに対するコンパイル中に潜在的な
nullの伝播を許容していました(詳細は Issue を参照)。= 1.3: コンパイラは欠落していたアサーションを生成します。これにより、誤って
nullを渡していたコードはより早く失敗する可能性があります。-XXLanguage:-StrictJavaNullabilityAssertionsを使用して、一時的に 1.3 以前の動作に戻すことができます。このフラグのサポートは、次のメジャーリリースで削除されます。
enum メンバに対する不適切なスマートキャスト
Issue: KT-20772
コンポーネント: コア言語
互換性のない変更の種類: ソース
概要: ある enum エントリのメンバに対するスマートキャストが、その enum エントリに対してのみ正しく適用されるようになります。
非推奨サイクル:
- < 1.3: ある enum エントリのメンバに対するスマートキャストが、他の enum エントリの同じメンバに対しても不適切なスマートキャストを引き起こす可能性がありました。
= 1.3: スマートキャストはその enum エントリのメンバに対してのみ正しく適用されます。
-XXLanguage:-SoundSmartcastForEnumEntriesを使用すると一時的に旧来の動作に戻ります。このフラグのサポートは、次のメジャーリリースで削除されます。
getter 内での val バッキングフィールドの再代入
Issue: KT-16681
コンポーネント: コア言語
互換性のない変更の種類: ソース
概要:
valプロパティの getter 内でそのバッキングフィールドを再代入することが禁止されました。非推奨サイクル:
- < 1.2: Kotlin コンパイラは getter 内で
valのバッキングフィールドを変更することを許可していました。これは Kotlin のセマンティクスに違反するだけでなく、finalフィールドを再代入するという不正な挙動の JVM バイトコードを生成していました。- 1.2.X:
valのバッキングフィールドを再代入するコードに対して非推奨の警告が報告されます。= 1.3: 非推奨の警告がエラーに格上げされました。
イテレートされる for ループの前での配列のキャプチャ
Issue: KT-21354
コンポーネント: Kotlin/JVM
互換性のない変更の種類: ソース
概要: for ループの範囲内にある式が、ループ内で更新されるローカル変数である場合、この変更はループの実行に影響を与えます。これは、範囲(range)、文字列(character sequence)、コレクションなどの他のコンテナに対するイテレーションとの整合性がありませんでした。
非推奨サイクル:
- < 1.2: 記述されたコードパターンは正常にコンパイルされますが、ローカル変数への更新がループの実行に影響を与えていました。
- 1.2.X: for ループ内の範囲式が配列型のローカル変数であり、かつループ内で代入が行われている場合に、非推奨の警告が報告されます。
- 1.3: このようなケースにおいて、他のコンテナと整合性のある動作に変更されました。
enum エントリ内のネストされた分類子
Issue: KT-16310
コンポーネント: コア言語
互換性のない変更の種類: ソース
概要: Kotlin 1.3 以降、enum エントリ内でのネストされた分類子(クラス、オブジェクト、インターフェース、アノテーションクラス、enum クラス)は禁止されます。
非推奨サイクル:
- < 1.2: enum エントリ内のネストされた分類子は正常にコンパイルされますが、実行時に例外で失敗することがありました。
- 1.2.X: ネストされた分類子に対して非推奨の警告が報告されます。
= 1.3: 非推奨の警告がエラーに格上げされました。
copy をオーバーライドするデータクラス
Issue: KT-19618
コンポーネント: コア言語
互換性のない変更の種類: ソース
概要: Kotlin 1.3 以降、データクラスが
copy()をオーバーライドすることは禁止されます。非推奨サイクル:
- < 1.2:
copy()をオーバーライドするデータクラスは正常にコンパイルされますが、実行時に失敗したり、奇妙な挙動を示したりすることがありました。- 1.2.X:
copy()をオーバーライドするデータクラスに対して非推奨の警告が報告されます。= 1.3: 非推奨の警告がエラーに格上げされました。
外部クラスからジェネリックパラメータをキャプチャして Throwable を継承するインナークラス
Issue: KT-17981
コンポーネント: コア言語
互換性のない変更の種類: ソース
概要: Kotlin 1.3 以降、インナークラスが
Throwableを継承することは許可されません。非推奨サイクル:
- < 1.2:
Throwableを継承するインナークラスは正常にコンパイルされます。そのようなインナークラスがジェネリックパラメータをキャプチャする場合、実行時に失敗する奇妙なコードパターンにつながる可能性がありました。- 1.2.X:
Throwableを継承するインナークラスに対して非推奨の警告が報告されます。= 1.3: 非推奨の警告がエラーに格上げされました。
コンパニオンオブジェクトを伴う複雑なクラス階層に関する可視性ルール
コンポーネント: コア言語
互換性のない変更の種類: ソース
概要: Kotlin 1.3 以降、コンパニオンオブジェクトやネストされた分類子を含む複雑なクラス階層において、短縮名による可視性のルールがより厳格になります。
非推奨サイクル:
- < 1.2: 旧来の可視性ルール(詳細は Issue を参照)
- 1.2.X: アクセスできなくなる短縮名に対して非推奨の警告が報告されます。ツールは、フルネームを追加することによる自動移行を提案します。
= 1.3: 非推奨の警告がエラーに格上げされました。該当するコードには、フルクオリファイア(完全修飾名)を追加するか、明示的なインポートを行う必要があります。
定数ではない vararg アノテーションパラメータ
Issue: KT-23153
コンポーネント: コア言語
互換性のない変更の種類: ソース
概要: Kotlin 1.3 以降、定数ではない値を vararg アノテーションパラメータとして設定することは禁止されます。
非推奨サイクル:
- < 1.2: コンパイラは vararg アノテーションパラメータに定数でない値を渡すことを許可していましたが、実際にはバイトコード生成中にその値を破棄しており、非自明な挙動を引き起こしていました。
- 1.2.X: そのようなコードパターンに対して非推奨の警告が報告されます。
= 1.3: 非推奨の警告がエラーに格上げされました。
ローカルアノテーションクラス
Issue: KT-23277
コンポーネント: コア言語
互換性のない変更の種類: ソース
概要: Kotlin 1.3 以降、ローカルアノテーションクラスはサポートされません。
非推奨サイクル:
- < 1.2: コンパイラはローカルアノテーションクラスを正常にコンパイルしていました。
- 1.2.X: ローカルアノテーションクラスに対して非推奨の警告が報告されます。
= 1.3: 非推奨の警告がエラーに格上げされました。
ローカル委譲プロパティに対するスマートキャスト
Issue: KT-22517
コンポーネント: コア言語
互換性のない変更の種類: ソース
概要: Kotlin 1.3 以降、ローカル委譲プロパティに対するスマートキャストは許可されません。
非推奨サイクル:
- < 1.2: コンパイラはローカル委譲プロパティのスマートキャストを許可していましたが、行儀の悪いデリゲートの場合に不適切なスマートキャストにつながる可能性がありました。
- 1.2.X: ローカル委譲プロパティに対するスマートキャストが非推奨として報告されます(コンパイラが警告を出します)。
= 1.3: 非推奨の警告がエラーに格上げされました。
mod 演算子の慣習
Issue: 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 への単一要素の受け渡し
Issue: KT-20588, KT-20589。KT-20171 も参照。
コンポーネント: コア言語
互換性のない変更の種類: ソース
概要: Kotlin 1.3 では、名前付き引数で vararg に単一の要素を代入することは非推奨となり、スプレッド演算子と配列作成の連続した使用に置き換える必要があります。
非推奨サイクル:
- < 1.2: 名前付き引数形式で vararg に単一の値を代入することは正常にコンパイルされ、配列の 単一 要素の代入として扱われていました。これにより、配列を vararg に代入する際に非自明な挙動が発生していました。
- 1.2.X: このような代入に対して非推奨の警告が報告され、ユーザーはスプレッド演算子と配列作成の組み合わせに切り替えるよう推奨されます。
- 1.3.X: 警告がエラーに格上げされました。
= 1.4: vararg への単一要素代入のセマンティクスを変更し、配列の代入を配列のスプレッド代入と同等にします。
ターゲットが EXPRESSION であるアノテーションの保持期間(Retention)
Issue: KT-13762
コンポーネント: コア言語
互換性のない変更の種類: ソース
概要: Kotlin 1.3 以降、ターゲットが
EXPRESSIONであるアノテーションにはSOURCE保持期間のみが許可されます。非推奨サイクル:
- < 1.2: ターゲットが
EXPRESSIONで保持期間がSOURCE以外のアノテーションも許可されていましたが、使用箇所では黙って無視されていました。- 1.2.X: そのようなアノテーションの宣言に対して非推奨の警告が報告されます。
= 1.3: 警告がエラーに格上げされました。
ターゲットが PARAMETER であるアノテーションは、パラメータの型に適用されるべきではない
Issue: KT-9580
コンポーネント: コア言語
互換性のない変更の種類: ソース
概要: Kotlin 1.3 以降、ターゲットが
PARAMETERであるアノテーションがパラメータの型に適用された場合、誤ったアノテーションターゲットに関するエラーが正しく報告されるようになります。非推奨サイクル:
- < 1.2: 前述のコードパターンは正常にコンパイルされていました。アノテーションは黙って無視され、バイトコードには存在しません。
- 1.2.X: そのような使用法に対して非推奨の警告が報告されます。
= 1.3: 警告がエラーに格上げされました。
Array.copyOfRange は、返される配列を拡大するのではなく、インデックスが範囲外の場合に例外をスローする
Issue: KT-19489
コンポーネント: kotlin-stdlib (JVM)
互換性のない変更の種類: 振る舞い
概要: Kotlin 1.3 以降、コピーされる範囲の排他的な終端を表す
Array.copyOfRangeのtoIndex引数が配列サイズを超えていないことを確認し、超えている場合はIllegalArgumentExceptionをスローするようにします。非推奨サイクル:
- < 1.3:
Array.copyOfRangeの呼び出しにおいてtoIndexが配列サイズより大きい場合、範囲内の不足している要素はnullで埋められ、Kotlin 型システムの健全性に違反していました。= 1.3:
toIndexが配列の範囲内にあることをチェックし、そうでない場合は例外をスローします。
Int および Long のプログレッシブ(progressions)で、ステップが Int.MIN_VALUE および Long.MIN_VALUE のものは禁止され、インスタンス化できなくなる
Issue: KT-17176
コンポーネント: kotlin-stdlib (JVM)
互換性のない変更の種類: 振る舞い
概要: Kotlin 1.3 以降、整数プログレッシブのステップ値がその整数型(
LongまたはInt)の最小負値になることを禁止します。これにより、IntProgression.fromClosedRange(0, 1, step = Int.MIN_VALUE)を呼び出すとIllegalArgumentExceptionがスローされます。非推奨サイクル:
- < 1.3:
Int.MIN_VALUEステップでIntProgressionを作成することが可能で、これは[0, -2147483648]という 2 つの値を生成していましたが、これは非自明な挙動でした。= 1.3: ステップがその整数型の最小負値である場合、
IllegalArgumentExceptionをスローします。
非常に長いシーケンスの操作におけるインデックスオーバーフローのチェック
Issue: KT-16097
コンポーネント: kotlin-stdlib (JVM)
互換性のない変更の種類: 振る舞い
概要: Kotlin 1.3 以降、長いシーケンスに対して
index、countおよび同様のメソッドがオーバーフローしないようにします。影響を受けるメソッドの全リストについては Issue を参照してください。非推奨サイクル:
- < 1.3: 非常に長いシーケンスに対してこれらのメソッドを呼び出すと、整数のオーバーフローにより負の結果が生成される可能性がありました。
= 1.3: これらのメソッドにおけるオーバーフローを検出し、直ちに例外をスローします。
空のマッチ正規表現による分割(split)結果のプラットフォーム間での統一
Issue: KT-21049
コンポーネント: kotlin-stdlib (JVM)
互換性のない変更の種類: 振る舞い
概要: Kotlin 1.3 以降、空のマッチ正規表現による
splitメソッドの動作をすべてのプラットフォームで統一します。非推奨サイクル:
- < 1.3: 前述の呼び出しの動作は、JS、JRE 6、JRE 7 と JRE 8+ を比較した場合に異なっていました。
= 1.3: プラットフォーム間で動作を統一します。
コンパイラ配布物における非推奨アーティファクトの廃止
Issue: 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 内のアノテーション
Issue: KT-21784
コンポーネント: kotlin-stdlib (JVM)
互換性のない変更の種類: バイナリ
概要: Kotlin 1.3 は、
org.jetbrains.annotationsパッケージのアノテーションを stdlib から削除し、コンパイラと共に提供される別のアーティファクトannotations-13.0.jarおよびmutability-annotations-compat.jarに移動します。非推奨サイクル:
- < 1.3: アノテーションは stdlib アーティファクトと共に提供されていました。
= 1.3: アノテーションは別のアーティファクトで提供されます。
