Kotlin 1.8.0の新機能
Kotlin 1.8.0がリリースされました。主なハイライトをいくつかご紹介します。
- JVM向けにディレクトリの内容を再帰的にコピーまたは削除する新しい実験的関数
- kotlin-reflectのパフォーマンス向上
- デバッグ体験を向上させる新しい-Xdebugコンパイラオプション
kotlin-stdlib-jdk7
とkotlin-stdlib-jdk8
がkotlin-stdlib
にマージ- Objective-C/Swift相互運用性の向上
- Gradle 7.3との互換性
IDEサポート
1.8.0をサポートするKotlinプラグインは、以下のIDEで利用可能です。
IDE | サポートされているバージョン |
---|---|
IntelliJ IDEA | 2021.3, 2022.1, 2022.2 |
Android Studio | Electric Eel (221), Flamingo (222) |
NOTE
IntelliJ IDEA 2022.3では、IDEプラグインを更新することなく、プロジェクトをKotlin 1.8.0に更新できます。
既存のプロジェクトをIntelliJ IDEA 2022.3でKotlin 1.8.0に移行するには、Kotlinのバージョンを1.8.0
に変更し、
GradleまたはMavenプロジェクトを再インポートします。
Kotlin/JVM
バージョン1.8.0から、コンパイラはJVM 19に対応するバイトコードバージョンのクラスを生成できるようになりました。 新しい言語バージョンには以下も含まれます。
- JVMアノテーションターゲットの生成をオフにするコンパイラオプション
- 最適化を無効にする新しい
-Xdebug
コンパイラオプション - 古いバックエンドの削除
- Lombokの@Builderアノテーションのサポート
TYPE_USEおよびTYPE_PARAMETERアノテーションターゲットを生成しない機能
KotlinアノテーションにKotlinターゲットとしてTYPE
が含まれている場合、そのアノテーションはJavaアノテーションターゲットのリストでjava.lang.annotation.ElementType.TYPE_USE
にマップされます。これは、TYPE_PARAMETER
Kotlinターゲットがjava.lang.annotation.ElementType.TYPE_PARAMETER
Javaターゲットにマップされるのと同様です。これは、APIレベルが26未満のAndroidクライアントにとって問題となります。これらのAPIレベルにはこれらのターゲットがAPIに含まれていないためです。
Kotlin 1.8.0から、新しいコンパイラオプション-Xno-new-java-annotation-targets
を使用して、TYPE_USE
およびTYPE_PARAMETER
アノテーションターゲットの生成を回避できます。
最適化を無効にする新しいコンパイラオプション
Kotlin 1.8.0では、デバッグ体験を向上させるために最適化を無効にする新しいコンパイラオプション-Xdebug
が追加されました。 現時点では、このオプションはコルーチンにおける「was optimized out」機能を無効にします。将来、さらに最適化が追加された際には、このオプションでそれらも無効にできるようになります。
「was optimized out」機能は、suspend関数を使用する際に変数を最適化します。しかし、最適化された変数はその値を確認できないため、コードのデバッグが困難になります。
古いバックエンドの削除
Kotlin 1.5.0で、IRベースのバックエンドが安定版(Stable)になったことを発表しました。 これは、Kotlin 1.4.*からの古いバックエンドが非推奨になったことを意味します。Kotlin 1.8.0では、古いバックエンドを完全に削除しました。 これにより、コンパイラオプション-Xuse-old-backend
およびGradleのuseOldBackend
オプションも削除されました。
Lombokの@Builderアノテーションのサポート
コミュニティからKotlin Lombok: Support generated builders (@Builder) YouTrack課題に多くの投票があったため、@Builder
アノテーションをサポートせざるを得ませんでした。
現時点では、@SuperBuilder
または@Tolerate
アノテーションをサポートする計画はありませんが、 @SuperBuilderと @Tolerateの課題に十分な投票があれば再検討します。
Lombokコンパイラプラグインの設定方法をご覧ください。
Kotlin/Native
Kotlin 1.8.0には、Objective-CおよびSwiftとの相互運用性の変更、Xcode 14.1のサポート、CocoaPods Gradleプラグインの改善が含まれています。
Xcode 14.1のサポート
Kotlin/Nativeコンパイラは、最新の安定版Xcodeバージョン14.1をサポートするようになりました。互換性の改善には以下の変更が含まれます。
- watchOSターゲット用に、Apple watchOSのARM64プラットフォームをサポートする新しい
watchosDeviceArm64
プリセットが追加されました。 - Kotlin CocoaPods Gradleプラグインでは、Appleフレームワーク向けのビットコード埋め込みがデフォルトで無効になりました。
- プラットフォームライブラリが、Appleターゲット向けのObjective-Cフレームワークの変更を反映するように更新されました。
Objective-C/Swift相互運用性の向上
KotlinとObjective-CおよびSwiftとの相互運用性を高めるために、3つの新しいアノテーションが追加されました。
@ObjCName
を使用すると、Kotlinの宣言をリネームする代わりに、SwiftまたはObjective-Cでより慣用的な名前を指定できます。このアノテーションは、Kotlinコンパイラに対し、このクラス、プロパティ、パラメータ、または関数にカスタムのObjective-CおよびSwift名を使用するよう指示します。
kotlin@ObjCName(swiftName = "MySwiftArray") class MyKotlinArray { @ObjCName("index") fun indexOf(@ObjCName("of") element: String): Int = TODO() } // Usage with the ObjCName annotations let array = MySwiftArray() let index = array.index(of: "element")
@HiddenFromObjC
を使用すると、Kotlinの宣言をObjective-Cから隠すことができます。このアノテーションは、Kotlinコンパイラに対し、関数またはプロパティをObjective-C(および結果としてSwift)にエクスポートしないよう指示します。これにより、KotlinコードをよりObjective-C/Swiftフレンドリーにすることができます。
@ShouldRefineInSwift
は、Kotlinの宣言をSwiftで書かれたラッパーに置き換える場合に便利です。このアノテーションは、Kotlinコンパイラに対し、生成されたObjective-C APIで関数またはプロパティを
swift_private
としてマークするよう指示します。このような宣言には__
プレフィックスが付けられ、Swiftコードからは見えなくなります。これらの宣言は、SwiftフレンドリーなAPIを作成するためにSwiftコードで引き続き使用できますが、例えばXcodeのオートコンプリートでは提案されません。
SwiftでObjective-C宣言を洗練する方法の詳細については、Appleの公式ドキュメントを参照してください。
NOTE
新しいアノテーションにはオプトインが必要です。
Kotlinチームは、これらのアノテーションを実装してくれたRick Clephasに非常に感謝しています。
CocoaPods Gradleプラグインにおける動的フレームワークのデフォルト化
Kotlin 1.8.0から、CocoaPods Gradleプラグインによって登録されたKotlinフレームワークは、デフォルトで動的にリンクされるようになりました。 以前の静的実装は、Kotlin Gradleプラグインの動作と整合性がありませんでした。
kotlin {
cocoapods {
framework {
baseName = "MyFramework"
isStatic = false // Now dynamic by default
}
}
}
既存のプロジェクトで静的リンクタイプを使用しており、Kotlin 1.8.0にアップグレードした場合(またはリンクタイプを明示的に変更した場合)、プロジェクトの実行でエラーが発生する可能性があります。これを修正するには、Xcodeプロジェクトを閉じて、Podfileディレクトリでpod install
を実行してください。
詳細については、CocoaPods GradleプラグインDSLリファレンスを参照してください。
Kotlin Multiplatform: 新しいAndroidソースセットレイアウト
Kotlin 1.8.0では、新しいAndroidソースセットレイアウトが導入されました。これは、これまでのディレクトリの命名規則が複数の点で混乱を招いていたため、それに代わるものです。
現在のレイアウトで作成される2つのandroidTest
ディレクトリの例を考えてみましょう。1つはKotlinSourceSets
用で、もう1つはAndroidSourceSets
用です。
- 意味が異なります。Kotlinの
androidTest
はunitTest
タイプに属しますが、AndroidのandroidTest
はintegrationTest
タイプに属します。 - 混乱を招く
SourceDirectories
レイアウトが作成されます。src/androidTest/kotlin
にはUnitTest
があり、src/androidTest/java
にはInstrumentedTest
があります。 KotlinSourceSets
とAndroidSourceSets
の両方がGradleの設定に同様の命名規則を使用するため、両方のKotlinとAndroidのソースセットのandroidTest
の最終的な設定はandroidTestImplementation
、androidTestApi
、androidTestRuntimeOnly
、androidTestCompileOnly
と同じになります。
これらの既存の問題に対処するために、新しいAndroidソースセットレイアウトが導入されました。 2つのレイアウトの主な違いをいくつか示します。
KotlinSourceSetの命名規則
現在のソースセットレイアウト | 新しいソースセットレイアウト |
---|---|
targetName + AndroidSourceSet.name | targetName + AndroidVariantType |
{AndroidSourceSet.name}
は、次のように{KotlinSourceSet.name}
にマッピングされます。
現在のソースセットレイアウト | 新しいソースセットレイアウト | |
---|---|---|
main | androidMain | androidMain |
test | androidTest | androidUnitTest |
androidTest | androidAndroidTest | androidInstrumentedTest |
SourceDirectories
現在のソースセットレイアウト | 新しいソースセットレイアウト |
---|---|
レイアウトは追加の/kotlin SourceDirectoriesを追加します | src/{AndroidSourceSet.name}/kotlin 、src/{KotlinSourceSet.name}/kotlin |
{AndroidSourceSet.name}
は、次のように{SourceDirectories included}
にマッピングされます。
現在のソースセットレイアウト | 新しいソースセットレイアウト | |
---|---|---|
main | src/androidMain/kotlin, src/main/kotlin, src/main/java | src/androidMain/kotlin, src/main/kotlin, src/main/java |
test | src/androidTest/kotlin, src/test/kotlin, src/test/java | src/androidUnitTest/kotlin, src/test/kotlin, src/test/java |
androidTest | src/androidAndroidTest/kotlin, src/androidTest/java | src/androidInstrumentedTest/kotlin, src/androidTest/java, src/androidTest/kotlin |
AndroidManifest.xmlファイルの場所
現在のソースセットレイアウト | 新しいソースセットレイアウト |
---|---|
src/{AndroidSourceSet.name}/AndroidManifest.xml | src/{KotlinSourceSet.name}/AndroidManifest.xml |
{AndroidSourceSet.name}
は、次のように{AndroidManifest.xml location}
にマッピングされます。
現在のソースセットレイアウト | 新しいソースセットレイアウト | |
---|---|---|
main | src/main/AndroidManifest.xml | src/androidMain/AndroidManifest.xml |
debug | src/debug/AndroidManifest.xml | src/androidDebug/AndroidManifest.xml |
Androidテストと共通テストの関係
新しいAndroidソースセットレイアウトは、Androidインストルメンテッドテスト(新しいレイアウトではandroidInstrumentedTest
に改名)と共通テストの関係を変更します。
以前は、androidAndroidTest
とcommonTest
の間にデフォルトのdependsOn
関係がありました。実際には、これは以下のことを意味していました。
commonTest
のコードがandroidAndroidTest
で利用可能でした。commonTest
のexpect
宣言は、androidAndroidTest
に対応するactual
実装を持つ必要がありました。commonTest
で宣言されたテストもAndroidインストルメンテッドテストとして実行されていました。
新しいAndroidソースセットレイアウトでは、dependsOn
関係はデフォルトでは追加されません。以前の動作を希望する場合は、build.gradle.kts
ファイルでこの関係を手動で宣言してください。
kotlin {
// ...
sourceSets {
val commonTest by getting
val androidInstrumentedTest by getting {
dependsOn(commonTest)
}
}
}
Androidフレーバーのサポート
以前は、Kotlin Gradleプラグインは、debug
およびrelease
ビルドタイプまたはdemo
やfull
などのカスタムフレーバーを持つAndroidソースセットに対応するソースセットを積極的に作成していました。 これにより、val androidDebug by getting { ... }
のような構造でアクセスできるようになっていました。
新しいAndroidソースセットレイアウトでは、これらのソースセットはafterEvaluate
フェーズで作成されます。これにより、そのような式は無効になり、org.gradle.api.UnknownDomainObjectException: KotlinSourceSet with name 'androidDebug' not found
のようなエラーが発生します。
これを回避するには、build.gradle.kts
ファイルで新しいinvokeWhenCreated()
APIを使用してください。
kotlin {
// ...
sourceSets.invokeWhenCreated("androidFreeDebug") {
// ...
}
}
設定とセットアップ
新しいレイアウトは今後のリリースでデフォルトになります。現在は以下のGradleオプションで有効にできます。
kotlin.mpp.androidSourceSetLayoutVersion=2
NOTE
新しいレイアウトにはAndroid Gradleプラグイン7.0以降が必要であり、Android Studio 2022.3以降でサポートされています。
以前のAndroidスタイルのディレクトリの使用は現在推奨されていません。Kotlin 1.8.0は非推奨サイクルの開始を告げ、現在のレイアウトに対する警告を導入しています。以下のGradleプロパティを使用すると、警告を抑制できます。
kotlin.mpp.androidSourceSetLayoutVersion1.nowarn=true
Kotlin/JS
Kotlin 1.8.0では、JS IRコンパイラバックエンドが安定化され、JavaScript関連のGradleビルドスクリプトに新機能が追加されました。
- 安定版JS IRコンパイラバックエンド
- yarn.lockが更新されたことを報告する新しい設定
- Gradleプロパティを介したブラウザのテストターゲットの追加
- プロジェクトにCSSサポートを追加する新しいアプローチ
安定版JS IRコンパイラバックエンド
このリリースから、Kotlin/JS中間表現(IRベース)コンパイラバックエンドが安定版(Stable)になりました。3つのバックエンドのインフラストラクチャを統一するのに時間がかかりましたが、現在ではKotlinコードに対して同じIRで動作します。
安定版JS IRコンパイラバックエンドの結果として、古いバックエンドは今後は非推奨となります。
安定版JS IRコンパイラとともに、インクリメンタルコンパイルがデフォルトで有効になりました。
まだ古いコンパイラを使用している場合は、移行ガイドを参考に新しいバックエンドにプロジェクトを切り替えてください。
yarn.lockが更新されたことを報告する新しい設定
yarn
パッケージマネージャーを使用している場合、yarn.lock
ファイルが更新された際に通知を受け取ることができる3つの新しい特別なGradle設定があります。これらの設定は、CIビルドプロセス中にyarn.lock
がサイレントに変更された場合に通知を受け取りたいときに使用できます。
これら3つの新しいGradleプロパティは次のとおりです。
YarnLockMismatchReport
:yarn.lock
ファイルの変更がどのように報告されるかを指定します。以下の値のいずれかを使用できます。FAIL
:対応するGradleタスクを失敗させます。これがデフォルトです。WARNING
:変更に関する情報を警告ログに書き込みます。NONE
:レポートを無効にします。
reportNewYarnLock
:新しく作成されたyarn.lock
ファイルを明示的に報告します。デフォルトでは、このオプションは無効になっています。これは、最初の起動時に新しいyarn.lock
ファイルを生成するのが一般的であるためです。このオプションを使用すると、ファイルがリポジトリにコミットされていることを確認できます。yarnLockAutoReplace
:Gradleタスクが実行されるたびにyarn.lock
を自動的に置き換えます。
これらのオプションを使用するには、build.gradle.kts
ファイルを次のように更新します。
import org.jetbrains.kotlin.gradle.targets.js.yarn.YarnLockMismatchReport
import org.jetbrains.kotlin.gradle.targets.js.yarn.YarnRootExtension
rootProject.plugins.withType(org.jetbrains.kotlin.gradle.targets.js.yarn.YarnPlugin::class.java) {
rootProject.the<YarnRootExtension>().yarnLockMismatchReport =
YarnLockMismatchReport.WARNING // NONE | FAIL
rootProject.the<YarnRootExtension>().reportNewYarnLock = false // true
rootProject.the<YarnRootExtension>().yarnLockAutoReplace = false // true
}
Gradleプロパティを介したブラウザのテストターゲットの追加
Kotlin 1.8.0から、異なるブラウザのテストターゲットをGradleプロパティファイル内で直接設定できるようになりました。これにより、build.gradle.kts
にすべてのターゲットを記述する必要がなくなるため、ビルドスクリプトファイルのサイズを縮小できます。
このプロパティを使用して、すべてのモジュールに対してブラウザのリストを定義し、特定のモジュールのビルドスクリプトに特定のブラウザを追加できます。
例えば、Gradleプロパティファイルの以下の行は、すべてのモジュールでFirefoxとSafariでテストを実行します。
kotlin.js.browser.karma.browsers=firefox,safari
プロパティに利用可能な値の完全なリストはGitHubで確認できます。
Kotlinチームは、この機能を実装してくれたMartynas Petuškaに非常に感謝しています。
プロジェクトにCSSサポートを追加する新しいアプローチ
このリリースでは、プロジェクトにCSSサポートを追加する新しいアプローチが提供されます。これにより多くのプロジェクトに影響が出ると予想されるため、以下に説明するようにGradleビルドスクリプトファイルを忘れずに更新してください。
Kotlin 1.8.0以前は、cssSupport.enabled
プロパティを使用してCSSサポートを追加していました。
browser {
commonWebpackConfig {
cssSupport.enabled = true
}
}
今後は、cssSupport {}
ブロック内でenabled.set()
メソッドを使用する必要があります。
browser {
commonWebpackConfig {
cssSupport {
enabled.set(true)
}
}
}
Gradle
Kotlin 1.8.0はGradleバージョン7.2および7.3を完全にサポートしています。最新のGradleリリースまで使用することもできますが、その場合は非推奨の警告に遭遇したり、一部の新しいGradle機能が動作しない可能性があることに留意してください。
このバージョンでは多くの変更が加えられています。
- KotlinコンパイラオプションのGradle遅延プロパティとしての公開
- 最小サポートバージョンの引き上げ
- Kotlinデーモンフォールバック戦略を無効にする機能
- 推移的依存関係における最新のkotlin-stdlibバージョンの使用
- 関連するKotlinとJavaコンパイルタスクのJVMターゲット互換性の強制的なチェック
- Kotlin Gradleプラグインの推移的依存関係の解決
- 非推奨化と削除
KotlinコンパイラオプションのGradle遅延プロパティとしての公開
利用可能なKotlinコンパイラオプションをGradle遅延プロパティとして公開し、Kotlinタスクにより適切に統合するために、多くの変更を加えました。
コンパイルタスクには、既存の
kotlinOptions
に似ていますが、戻り値の型としてGradle Properties APIのProperty
を使用する新しいcompilerOptions
入力があります。kotlintasks.named("compileKotlin", org.jetbrains.kotlin.gradle.tasks.KotlinJvmCompile::class.java) { compilerOptions { useK2.set(true) } }
Kotlinツールタスク
KotlinJsDce
とKotlinNativeLink
には、既存のkotlinOptions
入力に似た新しいtoolOptions
入力があります。新しい入力には
@Nested
Gradleアノテーションが付きます。入力内のすべてのプロパティには、@Input
や@Internal
などの関連するGradleアノテーションが付きます。一部の
compilerOptions
は、String
型ではなく新しい型を使用します。JvmTarget
KotlinVersion
(apiVersion
とlanguageVersion
の入力用)JsMainFunctionExecutionMode
JsModuleKind
JsSourceMapEmbedMode
例えば、
kotlinOptions.jvmTarget = "11"
の代わりにcompilerOptions.jvmTarget.set(JvmTarget.JVM_11)
を使用できます。kotlinOptions
の型は変更されておらず、内部的にcompilerOptions
型に変換されます。Kotlin GradleプラグインAPIは、以前のリリースとバイナリ互換性があります。ただし、
kotlin-gradle-plugin
アーティファクトには、ソースおよびABI互換性を破壊する変更がいくつかあります。これらの変更のほとんどは、一部の内部型に対する追加のジェネリックパラメータに関係します。重要な変更の1つは、KotlinNativeLink
タスクがAbstractKotlinNativeCompile
タスクを継承しなくなったことです。KotlinJsCompilerOptions.outputFile
および関連するKotlinJsOptions.outputFile
オプションは非推奨になりました。代わりにKotlin2JsCompile.outputFileProperty
タスク入力を使用してください。
NOTE
Kotlin Gradleプラグインは、引き続きKotlinJvmOptions
DSLをAndroid拡張機能に追加します。
android {
kotlinOptions {
jvmTarget = "11"
}
}
これは、compilerOptions
DSLがモジュールレベルに追加されるときに、この課題の範囲で変更される予定です。
制限事項
DANGER
kotlinOptions
タスク入力とkotlinOptions{...}
タスクDSLはサポートモードであり、
今後のリリースで非推奨になる予定です。改善はcompilerOptions
とtoolOptions
にのみ行われます。
kotlinOptions
のセッターまたはゲッターを呼び出すと、関連するcompilerOptions
のプロパティに委譲されます。 これにより、以下の制限が生じます。
compilerOptions
とkotlinOptions
は、タスク実行フェーズで変更できません(以下の段落の例外を参照)。freeCompilerArgs
は不変のList<String>
を返すため、例えばkotlinOptions.freeCompilerArgs.remove("something")
は失敗します。
kotlin-dsl
や、Jetpack Composeが有効になっているAndroid Gradleプラグイン(AGP)を含むいくつかのプラグインは、タスク実行フェーズでfreeCompilerArgs
属性を変更しようとします。Kotlin 1.8.0では、それらの回避策を追加しました。この回避策により、任意のビルドスクリプトまたはプラグインが実行フェーズでkotlinOptions.freeCompilerArgs
を変更できますが、ビルドログに警告が出力されます。この警告を無効にするには、新しいGradleプロパティkotlin.options.suppressFreeCompilerArgsModificationWarning=true
を使用します。 Gradleはkotlin-dsl
プラグインと Jetpack Composeが有効になっているAGPに対する修正を追加する予定です。
最小サポートバージョンの引き上げ
Kotlin 1.8.0から、サポートされるGradleの最小バージョンは6.8.3、サポートされるAndroid Gradleプラグインの最小バージョンは4.1.3です。
Kotlin Gradleプラグインと利用可能なGradleバージョンの互換性については、ドキュメントを参照してください。
Kotlinデーモンフォールバック戦略を無効にする機能
新しいGradleプロパティkotlin.daemon.useFallbackStrategy
があり、そのデフォルト値はtrue
です。値がfalse
の場合、デーモンの起動または通信に問題があるとビルドは失敗します。また、Kotlinコンパイルタスクには新しいuseDaemonFallbackStrategy
プロパティがあり、両方を使用している場合はGradleプロパティよりも優先されます。コンパイルを実行するためのメモリが不足している場合は、ログにその旨のメッセージが表示されます。
Kotlinコンパイラのフォールバック戦略は、デーモンが何らかの理由で失敗した場合に、Kotlinデーモンの外部でコンパイルを実行することです。Gradleデーモンがオンの場合、コンパイラは「In process」戦略を使用します。Gradleデーモンがオフの場合、コンパイラは「Out of process」戦略を使用します。これらの実行戦略の詳細については、ドキュメントを参照してください。別の戦略へのサイレントフォールバックは、多くのシステムリソースを消費したり、非決定的なビルドにつながる可能性があることに注意してください。詳細については、このYouTrack課題を参照してください。
推移的依存関係における最新のkotlin-stdlibバージョンの使用
依存関係でKotlinバージョン1.8.0以降を明示的に記述した場合(例: implementation("org.jetbrains.kotlin:kotlin-stdlib:1.8.0")
)、Kotlin Gradleプラグインは、推移的なkotlin-stdlib-jdk7
およびkotlin-stdlib-jdk8
依存関係にそのKotlinバージョンを使用します。これは、異なるstdlibバージョンからのクラスの重複を避けるために行われます(kotlin-stdlib-jdk7
とkotlin-stdlib-jdk8
のkotlin-stdlib
へのマージについて詳しくはこちら)。 この動作は、kotlin.stdlib.jdk.variants.version.alignment
Gradleプロパティで無効にできます。
kotlin.stdlib.jdk.variants.version.alignment=false
バージョンアライメントで問題が発生した場合は、ビルドスクリプトでkotlin-bom
にプラットフォーム依存関係を宣言することで、Kotlin BOMを介してすべてのバージョンをアライメントしてください。
implementation(platform("org.jetbrains.kotlin:kotlin-bom:1.8.0"))
その他のケースと推奨される解決策については、ドキュメントを参照してください。
関連するKotlinとJavaコンパイルタスクのJVMターゲット互換性の強制的なチェック
NOTE
このセクションは、ソースファイルがKotlinのみでJavaを使用していない場合でも、JVMプロジェクトに適用されます。
このリリースから、 Gradle 8.0以降のプロジェクト(このバージョンのGradleはまだリリースされていません)では、kotlin.jvm.target.validation.mode
プロパティのデフォルト値がerror
になり、JVMターゲットの互換性がない場合にプラグインがビルドを失敗させるようになります。
デフォルト値がwarning
からerror
に移行するのは、Gradle 8.0へのスムーズな移行のための準備ステップです。 このプロパティをerror
に設定することをお勧めします。そして、ツールチェーンを設定するか、手動でJVMバージョンを調整してください。
ターゲットの互換性をチェックしない場合に何が問題になるかについて詳しく学びましょう。
Kotlin Gradleプラグインの推移的依存関係の解決
Kotlin 1.7.0で、Gradleプラグインのバリアントのサポートを導入しました。 これらのプラグインバリアントのため、ビルドクラスパスには、通常kotlin-gradle-plugin-api
など、異なるバージョンの依存関係に依存する異なるバージョンのKotlin Gradleプラグインが含まれる可能性があります。これは解決の問題につながる可能性があり、kotlin-dsl
プラグインを例として、以下の回避策を提案します。
Gradle 7.6のkotlin-dsl
プラグインはorg.jetbrains.kotlin.plugin.sam.with.receiver:1.7.10
プラグインに依存し、これはkotlin-gradle-plugin-api:1.7.10
に依存します。org.jetbrains.kotlin.gradle.jvm:1.8.0
プラグインを追加すると、このkotlin-gradle-plugin-api:1.7.10
の推移的依存関係は、バージョン(1.8.0
と1.7.10
)とバリアント属性のorg.gradle.plugin.api-version
値の不一致により、依存関係の解決エラーを引き起こす可能性があります。回避策として、バージョンを揃えるためにこの制約を追加してください。この回避策は、Kotlin Gradleプラグインライブラリのアライメントプラットフォームを実装するまで必要になる場合があります。これは計画中です。
dependencies {
constraints {
implementation("org.jetbrains.kotlin:kotlin-sam-with-receiver:1.8.0")
}
}
この制約により、ビルドクラスパスで推移的依存関係にorg.jetbrains.kotlin:kotlin-sam-with-receiver:1.8.0
バージョンが強制的に使用されます。Gradle issue trackerの同様のケースについて詳しく学びましょう。
非推奨化と削除
Kotlin 1.8.0では、以下のプロパティとメソッドの非推奨サイクルが継続されます。
- Kotlin 1.7.0の注記で、
KotlinCompile
タスクには非推奨のKotlinプロパティclasspath
がまだ存在し、将来のリリースで削除されることが示されていました。今回、KotlinCompile
タスクのclasspath
プロパティの非推奨レベルをerror
に変更しました。すべてのコンパイルタスクは、コンパイルに必要なライブラリのリストにlibraries
入力を使用します。 - kaptをGradle Workers API経由で実行できるようにする
kapt.use.worker.api
プロパティを削除しました。 デフォルトで、kaptはKotlin 1.3.70以降Gradle workersを使用しています。この方法に固執することをお勧めします。 - Kotlin 1.7.0で、
kotlin.compiler.execution.strategy
プロパティの非推奨サイクル開始を発表しました。 このリリースで、このプロパティを削除しました。Kotlinコンパイラの実行戦略を定義する他の方法について学びましょう。
標準ライブラリ
Kotlin 1.8.0:
- JVMコンパイルターゲットを更新しました。
- いくつかの関数を安定化しました – JavaとKotlin間の
TimeUnit
変換、cbrt()
、JavaOptionals
拡張関数。 - 比較可能で減算可能な
TimeMarks
のプレビューを提供します。 java.nio.file.path
の実験的な拡張関数を含みます。- kotlin-reflectのパフォーマンスを向上させました。
更新されたJVMコンパイルターゲット
Kotlin 1.8.0では、標準ライブラリ(kotlin-stdlib
、kotlin-reflect
、kotlin-script-*
)がJVMターゲット1.8でコンパイルされるようになりました。以前は、標準ライブラリはJVMターゲット1.6でコンパイルされていました。
Kotlin 1.8.0はJVMターゲット1.6および1.7をサポートしなくなりました。結果として、kotlin-stdlib-jdk7
およびkotlin-stdlib-jdk8
の内容がkotlin-stdlib
にマージされたため、ビルドスクリプトでこれらを個別に宣言する必要がなくなりました。
NOTE
ビルドスクリプトでkotlin-stdlib-jdk7
およびkotlin-stdlib-jdk8
を明示的に依存関係として宣言している場合は、
それらをkotlin-stdlib
に置き換える必要があります。
stdlibアーティファクトの異なるバージョンを混在させると、クラスの重複やクラスの不足につながる可能性があることに注意してください。 これを避けるために、Kotlin Gradleプラグインはstdlibのバージョンを揃えるのに役立ちます。
cbrt()
double
またはfloat
の実数立方根を計算できるcbrt()
関数が安定版(Stable)になりました。
import kotlin.math.*
fun main() {
val num = 27
val negNum = -num
println("The cube root of ${num.toDouble()} is: " +
cbrt(num.toDouble()))
println("The cube root of ${negNum.toDouble()} is: " +
cbrt(negNum.toDouble()))
}
TimeUnitのJavaとKotlin間での変換
kotlin.time
のtoTimeUnit()
およびtoDurationUnit()
関数が安定版(Stable)になりました。Kotlin 1.6.0で実験的に導入されたこれらの関数は、KotlinとJava間の相互運用性を向上させます。これにより、Javaのjava.util.concurrent.TimeUnit
とKotlinのkotlin.time.DurationUnit
の間で簡単に変換できるようになりました。これらの関数はJVMでのみサポートされています。
import kotlin.time.*
// For use from Java
fun wait(timeout: Long, unit: TimeUnit) {
val duration: Duration = timeout.toDuration(unit.toDurationUnit())
...
}
比較可能で減算可能なTimeMarks
DANGER
TimeMarks
の新しい機能は実験的であり、
使用するには@OptIn(ExperimentalTime::class)
または@ExperimentalTime
でオプトインする必要があります。
Kotlin 1.8.0以前は、複数のTimeMarks
と現在の時間差を計算したい場合、一度に1つのTimeMark
でしかelapsedNow()
を呼び出すことができませんでした。このため、2つのelapsedNow()
関数呼び出しをまったく同時に実行することができなかったため、結果の比較が困難でした。
これを解決するために、Kotlin 1.8.0では、同じ時間ソースからのTimeMarks
を減算および比較できるようになりました。これで、現在を表す新しいTimeMark
インスタンスを作成し、そこから他のTimeMarks
を減算できます。これにより、これらの計算から収集される結果は、互いに対して相対的であることが保証されます。
import kotlin.time.*
fun main() {
val timeSource = TimeSource.Monotonic
val mark1 = timeSource.markNow()
Thread.sleep(500) // Sleep 0.5 seconds
val mark2 = timeSource.markNow()
// Before 1.8.0
repeat(4) { n ->
val elapsed1 = mark1.elapsedNow()
val elapsed2 = mark2.elapsedNow()
// Difference between elapsed1 and elapsed2 can vary depending
// on how much time passes between the two elapsedNow() calls
println("Measurement 1.${n + 1}: elapsed1=$elapsed1, " +
"elapsed2=$elapsed2, diff=${elapsed1 - elapsed2}")
}
println()
// Since 1.8.0
repeat(4) { n ->
val mark3 = timeSource.markNow()
val elapsed1 = mark3 - mark1
val elapsed2 = mark3 - mark2
// Now the elapsed times are calculated relative to mark3,
// which is a fixed value
println("Measurement 2.${n + 1}: elapsed1=$elapsed1, " +
"elapsed2=$elapsed2, diff=${elapsed1 - elapsed2}")
}
// It's also possible to compare time marks with each other
// This is true, as mark2 was captured later than mark1
println(mark2 > mark1)
}
この新しい機能は、異なるフレームを表す複数のTimeMarks
間の差を計算したり比較したりしたいアニメーション計算で特に役立ちます。
ディレクトリの再帰的なコピーまたは削除
DANGER
java.nio.file.path
のこれらの新しい関数は実験的です。
使用するには、@OptIn(kotlin.io.path.ExperimentalPathApi::class)
または@kotlin.io.path.ExperimentalPathApi
でオプトインする必要があります。
または、コンパイラオプション-opt-in=kotlin.io.path.ExperimentalPathApi
を使用することもできます。
java.nio.file.Path
の2つの新しい拡張関数、copyToRecursively()
とdeleteRecursively()
が導入されました。これらを使用すると、再帰的に以下を実行できます。
- ディレクトリとその内容を別の宛先にコピーします。
- ディレクトリとその内容を削除します。
これらの関数は、バックアッププロセスの一部として非常に役立ちます。
エラー処理
copyToRecursively()
を使用すると、onError
ラムダ関数をオーバーロードすることで、コピー中に例外が発生した場合の動作を定義できます。
sourceRoot.copyToRecursively(destinationRoot, followLinks = false,
onError = { source, target, exception ->
logger.logError(exception, "Failed to copy $source to $target")
OnErrorResult.TERMINATE
})
deleteRecursively()
を使用する場合、ファイルまたはフォルダの削除中に例外が発生すると、そのファイルまたはフォルダはスキップされます。削除が完了すると、deleteRecursively()
は発生したすべての例外を抑制された例外として含むIOException
をスローします。
ファイルの上書き
copyToRecursively()
が宛先ディレクトリにファイルが既に存在することを発見すると、例外が発生します。 代わりにファイルを上書きしたい場合は、overwrite
を引数として持ち、それをtrue
に設定するオーバーロードを使用してください。
fun setUpEnvironment(projectDirectory: Path, fixtureName: String) {
fixturesRoot.resolve(COMMON_FIXTURE_NAME)
.copyToRecursively(projectDirectory, followLinks = false)
fixturesRoot.resolve(fixtureName)
.copyToRecursively(projectDirectory, followLinks = false,
overwrite = true) // patches the common fixture
}
カスタムコピーアクション
独自のカスタムコピーロジックを定義するには、追加の引数としてcopyAction
を持つオーバーロードを使用します。 copyAction
を使用すると、好みの操作を含むラムダ関数を提供できます。
sourceRoot.copyToRecursively(destinationRoot, followLinks = false) { source, target ->
if (source.name.startsWith(".")) {
CopyActionResult.SKIP_SUBTREE
} else {
source.copyToIgnoringExistingDirectory(target, followLinks = false)
CopyActionResult.CONTINUE
}
}
これらの拡張関数に関する詳細については、APIリファレンスを参照してください。
Java Optionals拡張関数
Kotlin 1.7.0で導入された拡張関数が安定版(Stable)になりました。これらの関数は、JavaのOptionalクラスの操作を簡素化します。これらを使用すると、JVM上でOptional
オブジェクトをアンラップして変換し、Java APIの操作をより簡潔にすることができます。詳細については、Kotlin 1.7.0の新機能を参照してください。
kotlin-reflectのパフォーマンス向上
kotlin-reflect
がJVMターゲット1.8でコンパイルされるようになったという事実を利用し、内部キャッシュメカニズムをJavaのClassValue
に移行しました。以前はKClass
のみをキャッシュしていましたが、現在はKType
とKDeclarationContainer
もキャッシュしています。これらの変更により、typeOf()
の呼び出し時におけるパフォーマンスが大幅に向上しました。
ドキュメントの更新
Kotlinのドキュメントにはいくつかの注目すべき変更が加えられました。
改訂および新規ページ
- Gradleの概要 – Gradleビルドシステムを使用したKotlinプロジェクトの構成とビルド方法、利用可能なコンパイラオプション、Kotlin Gradleプラグインにおけるコンパイルとキャッシュについて学びます。
- JavaとKotlinのNull可能性 – JavaとKotlinのnull許容変数(possibly nullable variables)の扱い方における違いを確認します。
- Lincheckガイド – JVM上で並行アルゴリズムをテストするためのLincheckフレームワークのセットアップと使用方法を学びます。
新規および更新されたチュートリアル
- GradleとKotlin/JVMを始める – IntelliJ IDEAとGradleを使用してコンソールアプリケーションを作成します。
- KtorとSQLDelightを使用したマルチプラットフォームアプリの作成 – Kotlin Multiplatform Mobileを使用してiOSとAndroid向けのモバイルアプリケーションを作成します。
- Kotlin Multiplatformを始める – Kotlinを使用したクロスプラットフォームモバイル開発について学び、AndroidとiOSの両方で動作するアプリを作成します。
Kotlin 1.8.0のインストール
IntelliJ IDEA 2021.3、2022.1、および2022.2は、Kotlinプラグインをバージョン1.8.0に自動的に更新することを提案します。IntelliJ IDEA 2022.3には、今後のマイナーアップデートでKotlinプラグインのバージョン1.8.0がバンドルされる予定です。
NOTE
IntelliJ IDEA 2022.3で既存のプロジェクトをKotlin 1.8.0に移行するには、Kotlinのバージョンを1.8.0
に変更し、
GradleまたはMavenプロジェクトを再インポートします。
Android Studio Electric Eel (221)とFlamingo (222)については、Kotlinプラグインのバージョン1.8.0が今後のAndroid Studioのアップデートで提供される予定です。新しいコマンドラインコンパイラは、GitHubリリースページからダウンロードできます。
Kotlin 1.8.0の互換性ガイド
Kotlin 1.8.0は機能リリースであるため、以前の言語バージョンで書かれたコードと互換性のない変更をもたらす可能性があります。これらの変更の詳細なリストは、Kotlin 1.8.0の互換性ガイドで確認できます。