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以前の振る舞いに戻すことができます。
プライマリコンストラクタに委譲しないセカンダリenumクラスコンストラクタの禁止
課題: KT-35870
コンポーネント: コア言語
非互換変更タイプ: ソース
概要: Kotlin 1.5 では、プライマリコンストラクタに委譲しないセカンダリenumクラスコンストラクタが禁止されます。
非推奨化サイクル:
- < 1.5: 問題のあるコンストラクタに対して警告を導入
= 1.5: この警告をエラーに昇格。
-XXLanguage:-RequiredPrimaryConstructorDelegationCallInEnums
を使用すると、一時的に1.5以前の振る舞いに戻すことができます。
privateなインライン関数から匿名型を公開することの禁止
課題: KT-33917
コンポーネント: コア言語
非互換変更タイプ: ソース
概要: Kotlin 1.5 では、privateなインライン関数から匿名型を公開することが禁止されます。
非推奨化サイクル:
- < 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 の場合:
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 の場合:
Maven の場合:
xml<configuration> <args> <arg>-Xuse-old-backend</arg> </args> </configuration>
このフラグのサポートは、将来のリリースで削除される予定です。
委譲式にジェネリック呼び出しを含む委譲プロパティに対してnull可能性アサーションを生成
課題: KT-44304
コンポーネント: Kotlin/JVM
非互換変更タイプ: 振る舞い
概要: Kotlin 1.5 から、Kotlinコンパイラは、委譲式にジェネリック呼び出しを含む委譲プロパティに対してnull可能性アサーションを出力するようになります。
非推奨化サイクル:
- 1.5: 委譲プロパティに対してnull可能性アサーションを出力 (詳細は課題を参照)。
-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以前の振る舞いに戻すことができます。
名前付きvarargを持つ呼び出しにおける引数実行の正しい順序を使用
課題: KT-17691
コンポーネント: Kotlin/JVM
非互換変更タイプ: 振る舞い
概要: Kotlin 1.5 では、名前付き
vararg
を持つ呼び出しにおける引数実行の順序が変更されます。非推奨化サイクル:
- < 1.5: 問題のあるコンストラクタに対して警告を導入
= 1.5: この警告をエラーに昇格。
-XXLanguage:-UseCorrectExecutionOrderForVarargArguments
を使用すると、一時的に1.5以前の振る舞いに戻すことができます。
演算子関数呼び出しでパラメータのデフォルト値を使用
課題: KT-42064
コンポーネント: Kotlin/JVM
非互換変更タイプ: 振る舞い
概要: Kotlin 1.5 では、演算子呼び出しでパラメータのデフォルト値が使用されるようになります。
非推奨化サイクル:
- < 1.5: 以前の振る舞い (詳細は課題を参照)
= 1.5: 振る舞いが変更。
-XXLanguage:-JvmIrEnabledByDefault
を使用すると、一時的に1.5以前の振る舞いに戻すことができます。
通常のプログレッションが空の場合、forループで空の逆順プログレッションを生成
課題: KT-42533
コンポーネント: Kotlin/JVM
非互換変更タイプ: 振る舞い
概要: Kotlin 1.5 では、通常のプログレッションが空の場合、forループで空の逆順プログレッションが生成されるようになります。
非推奨化サイクル:
- < 1.5: 以前の振る舞い (詳細は課題を参照)
= 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: 以前の振る舞い (詳細は課題を参照)
- 1.5:
Char.equals
関数の振る舞いを変更
デフォルトロケールに依存する大文字・小文字変換APIの削除
課題: KT-43023
コンポーネント: kotlin-stdlib
非互換変更タイプ: ソース
概要: Kotlin 1.5 から、
String.toUpperCase()
のようなデフォルトロケールに依存する大文字・小文字変換関数が非推奨になります。非推奨化サイクル:
- 1.5: デフォルトロケールを使用する大文字・小文字変換関数を非推奨にし (詳細は課題を参照)、代替を提案。
コレクションのminおよびmax関数の戻り値を段階的に非null許容型に変更
課題: KT-38854
コンポーネント: kotlin-stdlib (JVM)
非互換変更タイプ: ソース
概要: コレクションの
min
およびmax
関数の戻り値型が1.6で非null許容型に変更されます。非推奨化サイクル:
- 1.4:
...OrNull
関数を同義語として導入し、影響を受けるAPIを非推奨化 (詳細は課題を参照)- 1.5.0: 影響を受けるAPIの非推奨レベルをエラーに昇格
=1.6: 影響を受けるAPIを非null許容型で再導入
浮動小数点型から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: 非推奨レベルをエラーに昇格
ツール
単一プロジェクトでkotlin-testの複数のJVMバリアントを混在させない
課題: 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を除外する場合です。
groovyconfigurations { testImplementation.get().exclude("org.jetbrains.kotlin", "kotlin-test-junit") }