Skip to content

Kotlin 1.8.0の新機能

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

Kotlin 1.8.0がリリースされました。主なハイライトをいくつかご紹介します。

IDEサポート

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

IDEサポートされているバージョン
IntelliJ IDEA2021.3, 2022.1, 2022.2
Android StudioElectric 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に対応するバイトコードバージョンのクラスを生成できるようになりました。 新しい言語バージョンには以下も含まれます。

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関数を使用する際に変数を最適化します。しかし、最適化された変数はその値を確認できないため、コードのデバッグが困難になります。

DANGER

本番環境でこのオプションを使用しないでください-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フレンドリーなAPIを作成するためにSwiftコードで引き続き使用できますが、例えばXcodeのオートコンプリートでは提案されません。

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

NOTE

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

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タイプに属します。
  • 混乱を招くSourceDirectoriesレイアウトが作成されます。src/androidTest/kotlinにはUnitTestがあり、src/androidTest/javaにはInstrumentedTestがあります。
  • KotlinSourceSetsAndroidSourceSetsの両方がGradleの設定に同様の命名規則を使用するため、両方のKotlinとAndroidのソースセットの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ソースセットに対応するソースセットを積極的に作成していました。 これにより、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

NOTE

新しいレイアウトには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ベース)コンパイラバックエンドが安定版(Stable)になりました。3つのバックエンドのインフラストラクチャを統一するのに時間がかかりましたが、現在ではKotlinコードに対して同じIRで動作します。

安定版JS IRコンパイラバックエンドの結果として、古いバックエンドは今後は非推奨となります。

安定版JS IRコンパイラとともに、インクリメンタルコンパイルがデフォルトで有効になりました。

まだ古いコンパイラを使用している場合は、移行ガイドを参考に新しいバックエンドにプロジェクトを切り替えてください。

yarn.lockが更新されたことを報告する新しい設定

yarnパッケージマネージャーを使用している場合、yarn.lockファイルが更新された際に通知を受け取ることができる3つの新しい特別なGradle設定があります。これらの設定は、CIビルドプロセス中にyarn.lockがサイレントに変更された場合に通知を受け取りたいときに使用できます。

これら3つの新しいGradleプロパティは次のとおりです。

  • YarnLockMismatchReportyarn.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機能が動作しない可能性があることに留意してください。

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

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アノテーションが付きます。

  • 一部の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タスク入力を使用してください。

NOTE

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

kotlin

android {

    kotlinOptions {

        jvmTarget = "11"

    }

}

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

制限事項

DANGER

kotlinOptionsタスク入力とkotlinOptions{...}タスクDSLはサポートモードであり、

今後のリリースで非推奨になる予定です。改善はcompilerOptionstoolOptionsにのみ行われます。

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ターゲット互換性の強制的なチェック

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.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 issue trackerの同様のケースについて詳しく学びましょう。

非推奨化と削除

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-jdk7およびkotlin-stdlib-jdk8の内容がkotlin-stdlibにマージされたため、ビルドスクリプトでこれらを個別に宣言する必要がなくなりました。

NOTE

ビルドスクリプトでkotlin-stdlib-jdk7およびkotlin-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

DANGER

TimeMarksの新しい機能は実験的であり、

使用するには@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間の差を計算したり比較したりしたいアニメーション計算で特に役立ちます。

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

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ラムダ関数をオーバーロードすることで、コピー中に例外が発生した場合の動作を定義できます。

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

ドキュメントの更新

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

改訂および新規ページ

  • Gradleの概要 – Gradleビルドシステムを使用したKotlinプロジェクトの構成とビルド方法、利用可能なコンパイラオプション、Kotlin Gradleプラグインにおけるコンパイルとキャッシュについて学びます。
  • JavaとKotlinのNull可能性 – JavaとKotlinのnull許容変数(possibly nullable variables)の扱い方における違いを確認します。
  • 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がバンドルされる予定です。

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の互換性ガイドで確認できます。