Kotlin 1.5 の互換性ガイド
言語の現代性を保つ と 快適なアップデート は、Kotlin 言語設計における 基本的な原則です。前者は、言語の進化を妨げる構文は削除されるべきであると述べており、 後者は、コードの移行をできるだけスムーズにするために、この削除が事前に十分に周知されるべきであると述べています。
言語の変更のほとんどは、更新の変更履歴やコンパイラの警告など、他のチャネルを通じてすでに発表されていましたが、 このドキュメントではそれらすべてを要約し、Kotlin 1.4 から Kotlin 1.5 への移行に関する完全なリファレンスを提供します。
基本的な用語
このドキュメントでは、いくつかの種類の互換性について説明します。
- ソース互換性:ソース互換性のない変更とは、これまで問題なく(エラーや警告なしで)コンパイルできていたコードが、それ以上コンパイルできなくなることです。
- バイナリ互換性:2つのバイナリ成果物は、それらを交換してもロードまたはリンクエラーが発生しない場合、バイナリ互換性があると言われます。
- 振る舞い互換性:変更が適用される前後で、同じプログラムが異なる振る舞いを示す場合、その変更は振る舞い互換性がないと言われます。
これらの定義は、純粋なKotlinのみに与えられていることを覚えておいてください。 他の言語(例えばJava)の観点から見たKotlinコードの互換性は、このドキュメントの範囲外です。
言語と標準ライブラリ
シグネチャ多相呼び出しにおけるスプレッド演算子の禁止
問題: KT-35226
コンポーネント: コア言語
互換性のない変更の種類: ソース互換性
概要: Kotlin 1.5 では、シグネチャ多相呼び出しにおけるスプレッド演算子 (
*
) の使用が禁止されます。非推奨サイクル:
- < 1.5: 呼び出しサイトでの問題のある演算子に対して警告を導入
>=
1.5: この警告をエラーに昇格-XXLanguage:-ProhibitSpreadOnSignaturePolymorphicCall
を使用すると、一時的に1.5以前の振る舞いに戻すことができます。
それらのクラスから見えない抽象メンバー(internal/package-private)を含む非抽象クラスの禁止
問題: KT-27825
コンポーネント: コア言語
互換性のない変更の種類: ソース互換性
概要: Kotlin 1.5 では、それらのクラスから見えない抽象メンバー(internal/package-private)を含む非抽象クラスが禁止されます。
非推奨サイクル:
- < 1.5: 問題のあるクラスに対して警告を導入
>=
1.5: この警告をエラーに昇格-XXLanguage:-ProhibitInvisibleAbstractMethodsInSuperclasses
を使用すると、一時的に1.5以前の振る舞いに戻すことができます。
JVMで非具体化型パラメータに基づく配列を具体化型引数として使用することの禁止
問題: KT-31227
コンポーネント: コア言語
互換性のない変更の種類: ソース互換性
概要: Kotlin 1.5 では、JVMで非具体化型パラメータに基づく配列を具体化型引数として使用することが禁止されます。
非推奨サイクル:
- < 1.5: 問題のある呼び出しに対して警告を導入
>=
1.5: この警告をエラーに昇格-XXLanguage:-ProhibitNonReifiedArraysAsReifiedTypeArguments
を使用すると、一時的に1.5以前の振る舞いに戻すことができます。
プライマリコンストラクタに委譲しないセカンダリ列挙型コンストラクタの禁止
問題: KT-35870
コンポーネント: コア言語
互換性のない変更の種類: ソース互換性
概要: Kotlin 1.5 では、プライマリコンストラクタに委譲しないセカンダリ列挙型コンストラクタが禁止されます。
非推奨サイクル:
- < 1.5: 問題のあるコンストラクタに対して警告を導入
>=
1.5: この警告をエラーに昇格-XXLanguage:-RequiredPrimaryConstructorDelegationCallInEnums
を使用すると、一時的に1.5以前の振る舞いに戻すことができます。
プライベートなインライン関数から匿名型を公開することの禁止
問題: KT-33917
コンポーネント: コア言語
互換性のない変更の種類: ソース互換性
概要: Kotlin 1.5 では、プライベートなインライン関数から匿名型を公開することが禁止されます。
非推奨サイクル:
- < 1.5: 問題のあるコンストラクタに対して警告を導入
>=
1.5: この警告をエラーに昇格-XXLanguage:-ApproximateAnonymousReturnTypesInPrivateInlineFunctions
を使用すると、一時的に1.5以前の振る舞いに戻すことができます。
SAM変換を伴う引数の後に非スプレッド配列を渡すことの禁止
問題: KT-35224
コンポーネント: コア言語
互換性のない変更の種類: ソース互換性
概要: Kotlin 1.5 では、SAM変換を伴う引数の後に非スプレッド配列を渡すことが禁止されます。
非推奨サイクル:
- 1.3.70: 問題のある呼び出しに対して警告を導入
>=
1.5: この警告をエラーに昇格-XXLanguage:-ProhibitVarargAsArrayAfterSamArgument
を使用すると、一時的に1.5以前の振る舞いに戻すことができます。
アンダースコア付きcatchブロックパラメータの特別なセマンティクスのサポート
問題: KT-31567
コンポーネント: コア言語
互換性のない変更の種類: ソース互換性
概要: Kotlin 1.5 では、catchブロックで例外のパラメータ名を省略するために使用されるアンダースコアシンボル (
_
) への参照が禁止されます。非推奨サイクル:
- 1.4.20: 問題のある参照に対して警告を導入
>=
1.5: この警告をエラーに昇格-XXLanguage:-ForbidReferencingToUnderscoreNamedParameterOfCatchBlock
を使用すると、一時的に1.5以前の振る舞いに戻すことができます。
SAM変換の実装戦略を匿名クラスベースから invokedynamic に変更
問題: KT-44912
コンポーネント: Kotlin/JVM
互換性のない変更の種類: 振る舞い互換性
概要: Kotlin 1.5 から、SAM(単一抽象メソッド)変換の実装戦略が、匿名クラスの生成から
invokedynamic
JVM命令の使用に変更されます。非推奨サイクル:
- 1.5: SAM変換の実装戦略を変更
-Xsam-conversions=class
を使用すると、以前に使用されていた実装スキームに戻すことができます。
JVM IRベースのバックエンドにおけるパフォーマンスの問題
問題: KT-48233
コンポーネント: Kotlin/JVM
互換性のない変更の種類: 振る舞い互換性
概要: Kotlin 1.5 では、Kotlin/JVM コンパイラにIRベースのバックエンドがデフォルトで使用されます。 以前の言語バージョンでは、古いバックエンドが引き続きデフォルトで使用されます。
Kotlin 1.5 で新しいコンパイラを使用すると、パフォーマンスの低下問題に遭遇する可能性があります。 これらのケースの修正に取り組んでいます。
非推奨サイクル:
- < 1.5: デフォルトで古いJVMバックエンドが使用される
>=
1.5: デフォルトでIRベースのバックエンドが使用される。Kotlin 1.5 で古いバックエンドを使用する必要がある場合は、 一時的に1.5以前の振る舞いに戻すために、プロジェクトの設定ファイルに以下の行を追加します。Gradle の場合:
kotlintasks.withType<org.jetbrains.kotlin.gradle.dsl.KotlinJvmCompile> { kotlinOptions.useOldBackend = true }
groovytasks.withType(org.jetbrains.kotlin.gradle.dsl.KotlinJvmCompile) { kotlinOptions.useOldBackend = true }
Maven の場合:
xml<configuration> <args> <arg>-Xuse-old-backend</arg> </args> </configuration>
このフラグのサポートは、今後のリリースで削除される予定です。
JVM IRベースのバックエンドにおける新しいフィールドソート
問題: KT-46378
コンポーネント: Kotlin/JVM
互換性のない変更の種類: 振る舞い互換性
概要: バージョン 1.5 から、Kotlin はIRベースのバックエンドを 使用し、JVMバイトコードのソート方法が異なります。古いバックエンドでは本体で宣言されたフィールドがコンストラクタで宣言されたフィールドの前に生成されていましたが、新しいバックエンドでは逆になります。 新しいソート順は、Java シリアライゼーションのように、フィールドの順序に依存するシリアライゼーションフレームワークを使用するプログラムの振る舞いを変更する可能性があります。
非推奨サイクル:
- < 1.5: デフォルトで古いJVMバックエンドが使用される。これは、本体で宣言されたフィールドがコンストラクタで宣言されたフィールドの前に来ます。
>=
1.5: デフォルトで新しいIRベースのバックエンドが使用される。コンストラクタで宣言されたフィールドが本体で宣言されたフィールドの前に生成されます。回避策として、 Kotlin 1.5 で一時的に古いバックエンドに切り替えることができます。そのためには、プロジェクトの設定ファイルに以下の行を追加します。Gradle の場合:
kotlintasks.withType<org.jetbrains.kotlin.gradle.dsl.KotlinJvmCompile> { kotlinOptions.useOldBackend = true }
groovytasks.withType(org.jetbrains.kotlin.gradle.dsl.KotlinJvmCompile) { kotlinOptions.useOldBackend = true }
Maven の場合:
xml<configuration> <args> <arg>-Xuse-old-backend</arg> </args> </configuration>
このフラグのサポートは、今後のリリースで削除される予定です。
デリゲート式でジェネリック呼び出しを含むデリゲートプロパティに対して null 可能性アサーションを生成
問題: KT-44304
コンポーネント: Kotlin/JVM
互換性のない変更の種類: 振る舞い互換性
概要: Kotlin 1.5 から、Kotlin コンパイラはデリゲート式でジェネリック呼び出しを含むデリゲートプロパティに対して null 可能性アサーションを発行します。
非推奨サイクル:
- 1.5: デリゲートプロパティに対して null 可能性アサーションを発行(詳細については Issue を参照)。
-Xuse-old-backend
または-language-version 1.4
を使用すると、一時的に1.5以前の振る舞いに戻すことができます。
@OnlyInputTypes でアノテーションされた型パラメータを持つ呼び出しに対する警告をエラーに昇格
問題: KT-45861
コンポーネント: コア言語
互換性のない変更の種類: ソース互換性
概要: Kotlin 1.5 では、型安全性を向上させるために、
contains
、indexOf
、assertEquals
のような無意味な引数を持つ呼び出しが禁止されます。非推奨サイクル:
- 1.4.0: 問題のあるコンストラクタに対して警告を導入
>=
1.5: この警告をエラーに昇格-XXLanguage:-StrictOnlyInputTypesChecks
を使用すると、一時的に1.5以前の振る舞いに戻すことができます。
名前付き可変長引数を持つ呼び出しにおける引数実行の正しい順序を使用
問題: KT-17691
コンポーネント: Kotlin/JVM
互換性のない変更の種類: 振る舞い互換性
概要: Kotlin 1.5 では、名前付き可変長引数を持つ呼び出しにおける引数実行の順序が変更されます。
非推奨サイクル:
- < 1.5: 問題のあるコンストラクタに対して警告を導入
>=
1.5: この警告をエラーに昇格-XXLanguage:-UseCorrectExecutionOrderForVarargArguments
を使用すると、一時的に1.5以前の振る舞いに戻すことができます。
演算子呼び出しにおけるパラメータのデフォルト値を使用
問題: KT-42064
コンポーネント: Kotlin/JVM
互換性のない変更の種類: 振る舞い互換性
概要: Kotlin 1.5 では、演算子呼び出しにおけるパラメータのデフォルト値が使用されます。
非推奨サイクル:
- < 1.5: 以前の振る舞い(詳細については Issue を参照)
>=
1.5: 振る舞いが変更される-XXLanguage:-JvmIrEnabledByDefault
を使用すると、一時的に1.5以前の振る舞いに戻すことができます。
通常のプログレッションが空の場合、forループで空の逆順プログレッションを生成
問題: KT-42533
コンポーネント: Kotlin/JVM
互換性のない変更の種類: 振る舞い互換性
概要: Kotlin 1.5 では、通常のプログレッションが空の場合、forループで空の逆順プログレッションを生成します。
非推奨サイクル:
- < 1.5: 以前の振る舞い(詳細については Issue を参照)
>=
1.5: 振る舞いが変更される-XXLanguage:-JvmIrEnabledByDefault
を使用すると、一時的に1.5以前の振る舞いに戻すことができます。
Charから数値、Charから数字への変換を整理
問題: KT-23451
コンポーネント: kotlin-stdlib
互換性のない変更の種類: ソース互換性
概要: Kotlin 1.5 から、Charから数値型への変換が非推奨になります。
非推奨サイクル:
- 1.5:
Char.toInt()/toShort()/toLong()/toByte()/toDouble()/toFloat()
およびLong.toChar()
のような逆関数を非推奨にし、代替案を提案
kotlin.text 関数における文字の大文字・小文字を区別しない比較の不整合
問題: KT-45496
コンポーネント: kotlin-stdlib
互換性のない変更の種類: 振る舞い互換性
概要: Kotlin 1.5 から、
Char.equals
は大文字・小文字を区別しない比較において、まず文字の大文字化された変種が等しいかどうかを比較し、次にそれらの大文字化された変種の小文字化された変種(文字自体とは対照的に)が等しいかどうかを比較することで改善されます。非推奨サイクル:
- < 1.5: 以前の振る舞い(詳細については Issue を参照)
- 1.5:
Char.equals
関数の振る舞いを変更
デフォルトのロケール依存大文字・小文字変換APIを削除
問題: KT-43023
コンポーネント: kotlin-stdlib
互換性のない変更の種類: ソース互換性
概要: Kotlin 1.5 から、
String.toUpperCase()
のようなデフォルトロケールに依存する大文字・小文字変換関数が非推奨になります。非推奨サイクル:
- 1.5: デフォルトロケールを持つ大文字・小文字変換関数を非推奨にし(詳細については Issue を参照)、代替案を提案
コレクションのminおよびmax関数の戻り値の型を段階的に非Nullableに変更
問題: KT-38854
コンポーネント: kotlin-stdlib (JVM)
互換性のない変更の種類: ソース互換性
概要: コレクションの
min
およびmax
関数の戻り値の型は、1.6で非Nullableに変更されます。非推奨サイクル:
- 1.4:
...OrNull
関数を同義語として導入し、影響を受けるAPIを非推奨にする(詳細については Issue を参照)- 1.5.0: 影響を受けるAPIの非推奨レベルをエラーに引き上げ
>=
1.6: 影響を受けるAPIを非Nullableの戻り値の型で再導入
浮動小数点型からShortおよびByteへの変換の非推奨レベルを上げる
問題: KT-30360
コンポーネント: kotlin-stdlib (JVM)
互換性のない変更の種類: ソース互換性
概要: Kotlin 1.4 で
WARNING
レベルで非推奨とされた浮動小数点型からShort
およびByte
への変換は、Kotlin 1.5.0 以降エラーになります。非推奨サイクル:
- 1.4:
Double.toShort()/toByte()
およびFloat.toShort()/toByte()
を非推奨にし、代替案を提案- 1.5.0: 非推奨レベルをエラーに引き上げ
ツール
単一プロジェクトで複数のJVM版 kotlin-test
を混在させない
問題: KT-40225
コンポーネント: Gradle
互換性のない変更の種類: 振る舞い互換性
概要: 異なるテストフレームワーク用の相互排他的な
kotlin-test
の複数のバリアントが、推移的な依存関係によってもたらされた場合、プロジェクト内に存在し得ました。 1.5.0 以降、Gradleは異なるテストフレームワーク用の相互排他的なkotlin-test
バリアントの混在を許可しません。非推奨サイクル:
- < 1.5: 異なるテストフレームワーク用の相互排他的な
kotlin-test
バリアントの混在が許可される>=
1.5: 振る舞いが変更される。 Gradleは「Cannot select module with conflict on capability...」のような例外をスローします。考えられる解決策は以下の通りです。
- 推移的依存関係がもたらすものと同じ
kotlin-test
バリアントと、それに対応するテストフレームワークを使用します。kotlin-test
バリアントを推移的に持ち込まない別の依存関係のバリアントを見つけ、使用したいテストフレームワークを使えるようにします。- 使用したいテストフレームワークと同じものを使用する別の
kotlin-test
バリアントを推移的に持ち込む、別の依存関係のバリアントを見つけます。- 推移的に持ち込まれるテストフレームワークを除外します。以下の例はJUnit 4を除外するためのものです。
groovyテストフレームワークを除外した後、アプリケーションをテストします。動作しなくなった場合は、除外した変更を元に戻し、 ライブラリが使用しているのと同じテストフレームワークを使用し、あなたのテストフレームワークを除外してください。configurations { testImplementation.get().exclude("org.jetbrains.kotlin", "kotlin-test-junit") }