Skip to content

Kotlin 1.8.0の新機能

リリース日: 2022年12月28日

Kotlin 1.8.0がリリースされました。主なハイライトは以下のとおりです。

IDEサポート

Kotlin 1.8.0をサポートするKotlinプラグインは、以下のIDEで利用できます。

IDEサポートされるバージョン
IntelliJ IDEA2021.3, 2022.1, 2022.2
Android StudioElectric Eel (221), Flamingo (222)

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に対応するバイトコードバージョンのクラスを生成できるようになりました。 新しい言語バージョンには、以下の機能も含まれています。

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に存在しないためです。

Kotlin 1.8.0から、新しいコンパイラオプション-Xno-new-java-annotation-targetsを使用することで、 TYPE_USEおよびTYPE_PARAMETERアノテーションターゲットの生成を回避できます。

最適化を無効にする新しいコンパイラオプション

Kotlin 1.8.0では、デバッグ体験を向上させるために最適化を無効にする新しい-Xdebugコンパイラオプションが追加されました。 現時点では、このオプションはコルーチンの「was optimized out」機能を無効にします。 将来的には、さらなる最適化が追加された後も、このオプションはそれらを無効にします。

「was optimized out」機能は、中断関数を使用する際に変数を最適化します。しかし、最適化された変数では値が見えないため、 コードのデバッグが困難になります。

本番環境ではこのオプションを絶対に使用しないでください: -Xdebugによるこの機能の無効化は、 メモリリークを引き起こす可能性があります

旧バックエンドの削除

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コードでSwiftに親しみやすいAPIを作成するために引き続き使用できますが、 例えばXcodeの自動補完では提案されません。

    SwiftでObjective-C宣言を洗練する方法の詳細については、 公式Appleドキュメントを参照してください。

新しいアノテーションはオプトインが必要です。

Kotlinチームは、これらのアノテーションを実装してくれたRick Clephasに非常に感謝しています。

CocoaPods Gradleプラグインにおける動的フレームワークのデフォルト化

Kotlin 1.8.0から、CocoaPods Gradleプラグインによって登録されるKotlinフレームワークは、デフォルトで動的にリンクされるようになりました。 以前の静的実装は、Kotlin Gradleプラグインの動作と一貫性がありませんでした。

kotlin
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のandroidTestunitTestタイプに属し、 AndroidのandroidTestintegrationTestタイプに属します。
  • src/androidTest/kotlinUnitTestを持ち、src/androidTest/javaInstrumentedTestを持つため、 混乱を招くSourceDirectoriesレイアウトが作成されます。
  • KotlinSourceSetsAndroidSourceSetsはどちらもGradle設定に類似した命名スキームを使用するため、 両方のandroidTestソースセットの結果として得られる設定は、 androidTestImplementationandroidTestApiandroidTestRuntimeOnlyandroidTestCompileOnlyと同じになります。

これらの既存の問題に対処するために、新しいAndroidソースセットレイアウトが導入されました。 2つのレイアウト間の主な違いをいくつか示します。

KotlinSourceSet命名スキーム

現在のソースセットレイアウト新しいソースセットレイアウト
targetName + AndroidSourceSet.nametargetName + AndroidVariantType

{AndroidSourceSet.name}{KotlinSourceSet.name}に以下のようにマップされます。

現在のソースセットレイアウト新しいソースセットレイアウト
mainandroidMainandroidMain
testandroidTestandroidUnitTest
androidTestandroidAndroidTestandroidInstrumentedTest

SourceDirectories

現在のソースセットレイアウト新しいソースセットレイアウト
レイアウトは追加の/kotlin SourceDirectoriesを追加しますsrc/{AndroidSourceSet.name}/kotlinsrc/{KotlinSourceSet.name}/kotlin

{AndroidSourceSet.name}{SourceDirectories included}に以下のようにマップされます。

現在のソースセットレイアウト新しいソースセットレイアウト
mainsrc/androidMain/kotlin, src/main/kotlin, src/main/javasrc/androidMain/kotlin, src/main/kotlin, src/main/java
testsrc/androidTest/kotlin, src/test/kotlin, src/test/javasrc/androidUnitTest/kotlin, src/test/kotlin, src/test/java
androidTestsrc/androidAndroidTest/kotlin, src/androidTest/javasrc/androidInstrumentedTest/kotlin, src/androidTest/java, src/androidTest/kotlin

AndroidManifest.xmlファイルの場所

現在のソースセットレイアウト新しいソースセットレイアウト
src/{AndroidSourceSet.name}/AndroidManifest.xmlsrc/{KotlinSourceSet.name}/AndroidManifest.xml

{AndroidSourceSet.name}{AndroidManifest.xml location}に以下のようにマップされます。

現在のソースセットレイアウト新しいソースセットレイアウト
mainsrc/main/AndroidManifest.xmlsrc/androidMain/AndroidManifest.xml
debugsrc/debug/AndroidManifest.xmlsrc/androidDebug/AndroidManifest.xml

Androidと共通テストの関係

新しいAndroidソースセットレイアウトは、Android計装テスト(新しいレイアウトではandroidInstrumentedTestに改名)と 共通テストの関係を変更します。

以前は、androidAndroidTestcommonTestの間にデフォルトのdependsOn関係がありました。 実際には、これは以下のことを意味していました。

  • commonTestのコードはandroidAndroidTestで利用可能でした。
  • commonTestexpect宣言には、androidAndroidTestに対応するactual実装が必要でした。
  • commonTestで宣言されたテストも、Android計装テストとして実行されました。

新しいAndroidソースセットレイアウトでは、dependsOn関係はデフォルトでは追加されません。 以前の動作を希望する場合は、build.gradle.ktsファイルでこの関係を手動で宣言してください。

kotlin
kotlin {
    // ...
    sourceSets {
        val commonTest by getting
        val androidInstrumentedTest by getting {
            dependsOn(commonTest)
        }
    }
}

Androidフレーバーのサポート

以前は、Kotlin Gradleプラグインは、debugおよびreleaseビルドタイプ、またはdemofullなどのカスタムフレーバーに対応するAndroidソースセットを eagerly に作成していました。 これにより、val androidDebug by getting { ... }のような構成でアクセスできるようになりました。

新しいAndroidソースセットレイアウトでは、これらのソースセットはafterEvaluateフェーズで作成されます。 そのため、このような式は無効となり、org.gradle.api.UnknownDomainObjectException: KotlinSourceSet with name 'androidDebug' not found のようなエラーが発生します。

これを回避するには、build.gradle.ktsファイルで新しいinvokeWhenCreated() APIを使用します。

kotlin
kotlin {
    // ...
    sourceSets.invokeWhenCreated("androidFreeDebug") {
        // ...
    }
}

設定とセットアップ

この新しいレイアウトは、将来のリリースでデフォルトになります。以下のGradleオプションで現在有効にできます。

none
kotlin.mpp.androidSourceSetLayoutVersion=2

この新しいレイアウトには、Android Gradleプラグイン7.0以降が必要であり、Android Studio 2022.3以降でサポートされています。

以前のAndroidスタイルディレクトリの使用は非推奨となりました。 Kotlin 1.8.0は非推奨化サイクルの始まりを示し、現在のレイアウトに対する警告が導入されます。 以下のGradleプロパティを使用すると、この警告を抑制できます。

none
kotlin.mpp.androidSourceSetLayoutVersion1.nowarn=true

Kotlin/JS

Kotlin 1.8.0は、JS IRコンパイラバックエンドを安定化させ、JavaScript関連のGradleビルドスクリプトに新機能をもたらします。

安定版JS IRコンパイラバックエンド

このリリースから、Kotlin/JS中間表現(IRベース)コンパイラバックエンドが安定版になりました。 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ファイルを次のように更新します。

kotlin
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でテストを実行します。

none
kotlin.js.browser.karma.browsers=firefox,safari

プロパティに利用可能な値の完全なリストはGitHubで参照してください。

Kotlinチームは、この機能を実装してくれたMartynas Petuškaに深く感謝しています。

プロジェクトにCSSサポートを追加する新しいアプローチ

このリリースでは、プロジェクトにCSSサポートを追加する新しいアプローチを提供します。 これにより多くのプロジェクトに影響が出ると予想されるため、以下に説明するようにGradleビルドスクリプトファイルを更新することを忘れないでください。

Kotlin 1.8.0より前は、cssSupport.enabledプロパティを使用してCSSサポートを追加していました。

kotlin
browser {
    commonWebpackConfig {
        cssSupport.enabled = true
    }
}

現在では、cssSupport {}ブロック内のenabled.set()メソッドを使用する必要があります。

kotlin
browser {
    commonWebpackConfig {
        cssSupport {
            enabled.set(true)
        }
    }
}

Gradle

Kotlin 1.8.0は、Gradleバージョン7.2および7.3を完全にサポートしています。 最新のGradleリリースまでのGradleバージョンも使用できますが、その場合、非推奨の警告や一部の新しいGradle機能が動作しない可能性があることに注意してください。

このバージョンでは多くの変更が加えられています。

KotlinコンパイラオプションのGradle遅延プロパティとしての公開

利用可能なKotlinコンパイラオプションをGradle遅延プロパティ として公開し、Kotlinタスクにさらに統合するために、多くの変更が加えられました。

  • コンパイルタスクには、既存のkotlinOptionsに似ていますが、 戻り値の型としてGradle Properties APIのProperty を使用する新しいcompilerOptions入力があります。

    kotlin
    tasks.named("compileKotlin", org.jetbrains.kotlin.gradle.tasks.KotlinJvmCompile::class.java) {
        compilerOptions {
            useK2.set(true)
        }
    }
  • KotlinツールタスクKotlinJsDceKotlinNativeLinkには、既存のkotlinOptions入力に似た新しいtoolOptions入力があります。

  • 新しい入力は@Nested Gradleアノテーションを持ちます。 入力内のすべてのプロパティには、@Input@Internal などの関連するGradleアノテーションがあります。

  • Kotlin GradleプラグインAPIアーティファクトには、2つの新しいインターフェースがあります。

    • org.jetbrains.kotlin.gradle.tasks.KotlinCompilationTask: compilerOptions入力とcompileOptions()メソッドを持ちます。 すべてのKotlinコンパイルタスクがこのインターフェースを実装します。
    • org.jetbrains.kotlin.gradle.tasks.KotlinToolTask: toolOptions入力とtoolOptions()メソッドを持ちます。 すべてのKotlinツールタスク(KotlinJsDceKotlinNativeLinkKotlinNativeLinkArtifactTask)がこのインターフェースを実装します。
  • 一部のcompilerOptionsは、String型ではなく新しい型を使用します。

    例: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タスク入力を使用してください。

Kotlin Gradleプラグインは、引き続きKotlinJvmOptions DSLをAndroid拡張機能に追加します。

kotlin
android { 
    kotlinOptions {
        jvmTarget = "11"
    }
}

これは、compilerOptions DSLがモジュールレベルに追加される際に、この課題の範囲で変更される予定です。

制限事項

kotlinOptionsタスク入力およびkotlinOptions{...}タスクDSLはサポートモードであり、 将来のリリースで非推奨になる予定です。改善はcompilerOptionsおよびtoolOptionsのみに行われます。

kotlinOptionsに対する任意のセッターまたはゲッター呼び出しは、compilerOptions内の関連プロパティに委譲されます。 これにより、以下の制限が生じます。

  • compilerOptionskotlinOptionsは、タスク実行フェーズで変更できません(以下の段落の例外を参照)。
  • 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-jdk7kotlin-stdlib-jdk8kotlin-stdlibに統合の詳細を参照)。 この動作は、kotlin.stdlib.jdk.variants.version.alignment Gradleプロパティで無効にできます。

none
kotlin.stdlib.jdk.variants.version.alignment=false

バージョンアラインメントで問題が発生した場合は、Kotlin BOM を介してすべてのバージョンをアラインするために、ビルドスクリプトでkotlin-bomへのプラットフォーム依存関係を宣言してください。

kotlin
implementation(platform("org.jetbrains.kotlin:kotlin-bom:1.8.0"))

その他のケースと提案されている解決策については、ドキュメントを参照してください。

関連するKotlinとJavaコンパイルタスクのJVMターゲット互換性一致に対する強制的なチェック

このセクションは、ソースファイルが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.01.7.10)とバリアント属性のorg.gradle.plugin.api-version値との不一致により、 依存関係解決エラーを引き起こす可能性があります。 回避策として、バージョンをアラインするためにこの制約を追加してください。 この回避策は、Kotlin Gradleプラグインライブラリのアラインメントプラットフォーム (計画中)が実装されるまで必要になる場合があります。

kotlin
dependencies {
    constraints {
        implementation("org.jetbrains.kotlin:kotlin-sam-with-receiver:1.8.0")
    }
}

この制約により、ビルドクラスパスの推移的依存関係でorg.jetbrains.kotlin:kotlin-sam-with-receiver:1.8.0バージョンが強制的に使用されます。 同様のGradle課題トラッカーのケースについては、 詳細を参照してください。

非推奨と削除

Kotlin 1.8.0では、以下のプロパティとメソッドの非推奨化サイクルが継続されます。

標準ライブラリ

Kotlin 1.8.0:

更新されたJVMコンパイルターゲット

Kotlin 1.8.0では、標準ライブラリ(kotlin-stdlibkotlin-reflectkotlin-script-*)はJVMターゲット1.8でコンパイルされます。 以前は、標準ライブラリはJVMターゲット1.6でコンパイルされていました。

Kotlin 1.8.0は、JVMターゲット1.6および1.7をサポートしなくなりました。 結果として、これらのアーティファクトの内容がkotlin-stdlibに統合されたため、 ビルドスクリプトでkotlin-stdlib-jdk7kotlin-stdlib-jdk8を個別に宣言する必要がなくなりました。

kotlin-stdlib-jdk7kotlin-stdlib-jdk8をビルドスクリプトで明示的に依存関係として宣言している場合は、 それらをkotlin-stdlibに置き換える必要があります。

異なるバージョンのstdlibアーティファクトを混在させると、クラスの重複やクラスの欠落につながる可能性があることに注意してください。 これを避けるために、Kotlin Gradleプラグインがstdlibバージョンのアラインメントに役立ちます。

cbrt()

doubleまたはfloatの実数立方根を計算できるcbrt()関数がStableになりました。

kotlin
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.timetoTimeUnit()およびtoDurationUnit()関数がStableになりました。 Kotlin 1.6.0で実験的として導入されたこれらの関数は、KotlinとJava間の相互運用性を向上させます。 これで、Javaのjava.util.concurrent.TimeUnitとKotlinのkotlin.time.DurationUnitの間で簡単に変換できます。 これらの関数はJVMでのみサポートされています。

kotlin
import kotlin.time.*

// For use from Java
fun wait(timeout: Long, unit: TimeUnit) {
    val duration: Duration = timeout.toDuration(unit.toDurationUnit())
    ...
}

比較可能で減算可能なTimeMarks

TimeMarksの新しい機能はExperimentalであり、 使用するには@OptIn(ExperimentalTime::class)または@ExperimentalTimeでオプトインする必要があります。

Kotlin 1.8.0より前では、複数のTimeMarks現在との時間差を計算したい場合、 一度に1つのTimeMarkでしかelapsedNow()を呼び出すことができませんでした。 これにより、2つのelapsedNow()関数呼び出しが正確に同時に実行できないため、結果を比較することが困難でした。

これを解決するため、Kotlin 1.8.0では、同じ時間ソースからのTimeMarksを減算および比較できるようになりました。 これにより、現在を表す新しいTimeMarkインスタンスを作成し、そこから他のTimeMarksを減算できます。 こうすることで、これらの計算から収集される結果は、互いに相対的であることが保証されます。

kotlin
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間の差を計算したり比較したりしたいアニメーション計算において特に有用です。

ディレクトリの再帰的なコピーまたは削除

java.nio.file.pathのこれらの新しい関数はExperimentalです。 これらを使用するには、@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ラムダ関数をオーバーロードすることで定義できます。

kotlin
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に設定するオーバーロードを使用します。

kotlin
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を使用すると、たとえば、好みの動作を持つラムダ関数を提供できます。

kotlin
sourceRoot.copyToRecursively(destinationRoot, followLinks = false) { source, target ->
    if (source.name.startsWith(".")) {
        CopyActionResult.SKIP_SUBTREE
    } else {
        source.copyToIgnoringExistingDirectory(target, followLinks = false)
        CopyActionResult.CONTINUE
    }
}

これらの拡張関数の詳細については、APIリファレンスを参照してください。

Java Optional拡張関数

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のみをキャッシュしていましたが、現在はKTypeKDeclarationContainerもキャッシュしています。 これらの変更により、typeOf()呼び出し時のパフォーマンスが大幅に向上しました。

ドキュメントの更新

Kotlinのドキュメントにいくつかの注目すべき変更が加えられました。

改訂されたページと新規ページ

  • Gradleの概要 – GradleビルドシステムでKotlinプロジェクトを設定およびビルドする方法、 利用可能なコンパイラオプション、Kotlin Gradleプラグインでのコンパイルとキャッシュについて学びます。
  • JavaとKotlinのNull可能性 – JavaとKotlinの、 nullの可能性がある変数を扱うアプローチの違いを確認します。
  • Lincheckガイド – JVM上の並行アルゴリズムをテストするためのLincheckフレームワークのセットアップと使用方法を学びます。

新規および更新されたチュートリアル

Kotlin 1.8.0のインストール

IntelliJ IDEA 2021.3、2022.1、および2022.2は、Kotlinプラグインをバージョン1.8.0に更新することを自動的に提案します。 IntelliJ IDEA 2022.3には、今後のマイナーアップデートでKotlinプラグインのバージョン1.8.0がバンドルされる予定です。

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の互換性ガイドで確認してください。