Skip to content

Kotlin 2.2.0-RC の新機能

リリース日: May 16, 2025

NOTE

このドキュメントは、Early Access Preview (EAP) リリースのすべての機能について説明するものではありませんが、

主要な改善点についてハイライトしています。

変更点の完全なリストは、GitHub changelog を参照してください。

Kotlin 2.2.0-RC がリリースされました! このEAPリリースの詳細を以下に示します。

IDEサポート

Kotlin 2.2.0-RC をサポートするKotlinプラグインは、最新のIntelliJ IDEAおよびAndroid Studioにバンドルされています。 IDEのKotlinプラグインを更新する必要はありません。 必要なのは、ビルドスクリプトでKotlinのバージョンを 2.2.0-RC に変更することだけです。

詳細については、新しいリリースへの更新 を参照してください。

言語

このリリースでは、いくつかの言語機能が安定版として昇格され、コンテキストパラメータがプレビューとして導入されました。

安定版機能: ガード条件、非ローカルなbreakcontinue、およびマルチダラー補間

Kotlin 2.1.0では、いくつかの新しい言語機能がプレビューで導入されました。 これらの言語機能がこのリリースで安定版になったことをお知らせいたします。

Kotlinの言語設計機能と提案の全リスト を参照してください。

コンテキストパラメータのプレビュー

このリリースでは、コンテキストパラメータがプレビューで導入されます。 コンテキストパラメータにより、関数やプロパティは、囲むコンテキストで暗黙的に利用可能な依存関係を宣言できます。

この機能は、以前の実験的機能であるコンテキストレシーバを置き換えるものです。コンテキストレシーバからコンテキストパラメータへの移行には、ブログ投稿で説明されているIntelliJ IDEAの支援サポートを使用できます。

コンテキストパラメータの宣言方法

プロパティと関数に対して、contextキーワードの後にname: Type形式のパラメータリストを続けることで、コンテキストパラメータを宣言できます。以下は、UserServiceインターフェースへの依存関係を持つ例です。

kotlin
// `UserService` defines the dependency required in context 
interface UserService {
    fun log(message: String)
    fun findUserById(id: Int): String
}

// Declares a function with a context parameter
context(users: UserService)
fun outputMessage(message: String) {
    // Uses `log` from the context
    users.log("Log: $message")
}

// Declares a property with a context parameter
context(users: UserService)
val firstUser: String
    // Uses `findUserById` from the context    
    get() = users.findUserById(1)

コンテキストパラメータ名として_を使用できます。この場合、パラメータの値は解決のために利用可能ですが、ブロック内で名前でアクセスすることはできません。

kotlin
// Uses `_` as context parameter name
context(_: UserService)
fun logWelcome() {
    // Resolution still finds the appropriate `log` function from UserService
    outputMessage("Welcome!")
}

コンテキストパラメータの解決

Kotlinは、現在のスコープで一致するコンテキスト値を検索することで、呼び出しサイトでコンテキストパラメータを解決します。Kotlinは型によってそれらを照合します。 同じスコープレベルに複数の互換性のある値が存在する場合、コンパイラは曖昧さを報告します。

kotlin
// `UserService` defines the dependency required in context
interface UserService {
    fun log(message: String)
}

// Declares a function with a context parameter
context(users: UserService)
fun outputMessage(message: String) {
    users.log("Log: $message")
}

fun main() {
    // Implements `UserService` 
    val serviceA = object : UserService {
        override fun log(message: String) = println("A: $message")
    }

    // Implements `UserService`
    val serviceB = object : UserService {
        override fun log(message: String) = println("B: $message")
    }

    // Both `serviceA` and `serviceB` match the expected `UserService` type at the call site
    context(serviceA, serviceB) {
        outputMessage("This will not compile")
        // Ambiguity error
    }
}

制限事項

コンテキストパラメータは継続的に改善されています。現在の制限事項の一部は次のとおりです。

  • コンストラクタはコンテキストパラメータを宣言できません
  • コンテキストパラメータを持つプロパティはバッキングフィールドまたは初期化子を持つことができません
  • コンテキストパラメータを持つプロパティはデリゲーションを使用できません

しかし、Kotlinのコンテキストパラメータは、簡素化された依存性注入、改善されたDSL設計、およびスコープ付き操作を通じて依存関係を管理する上で重要な改善を表しています。詳細については、機能のKEEPを参照してください。

コンテキストパラメータを有効にする方法

プロジェクトでコンテキストパラメータを有効にするには、コマンドラインで次のコンパイラオプションを使用します。

Bash
-Xcontext-parameters

または、GradleビルドファイルのcompilerOptions {}ブロックに追加します。

kotlin
// build.gradle.kts
kotlin {
    compilerOptions {
        freeCompilerArgs.add("-Xcontext-parameters")
    }
}

DANGER

-Xcontext-receivers-Xcontext-parametersの両方のコンパイラオプションを同時に指定すると、エラーが発生します。

フィードバックを送る

この機能は、将来のKotlinリリースで安定化され、改善される予定です。 IssueトラッカーのYouTrackで皆様からのフィードバックをいただければ幸いです。

Kotlinコンパイラ: コンパイラの警告の統一管理

Kotlin 2.2.0-RC では、 -Xwarning-level という新しいコンパイラオプションが導入されました。これは、Kotlinプロジェクトにおけるコンパイラの警告を統一的に管理するために設計されています。

以前は、-nowarnですべての警告を無効にしたり、-Werrorですべての警告をコンパイルエラーにしたり、-Wextraで追加のコンパイラチェックを有効にしたりするなど、一般的なモジュール全体のルールしか適用できませんでした。特定の警告に対してそれらを調整する唯一のオプションは、-Xsuppress-warningオプションでした。

この新しいソリューションにより、一般的なルールをオーバーライドし、特定の診断を一貫した方法で除外できます。

適用方法

新しいコンパイラオプションには、次の構文があります。

bash
-Xwarning-level=DIAGNOSTIC_NAME:(error|warning|disabled)
  • error: 指定された警告をエラーに昇格させます。
  • warning: 警告を出力し、デフォルトで有効です。
  • disabled: 指定された警告をモジュール全体で完全に抑制します。

新しいコンパイラオプションでは、警告 の深刻度レベルのみを設定できることに注意してください。

ユースケース

新しいソリューションを使用すると、一般的なルールと特定のルールを組み合わせることで、プロジェクトにおける警告レポートをより細かく調整できます。ユースケースを選択してください。

警告の抑制

コマンド説明
-nowarnコンパイル中のすべての警告を抑制します。
-Xwarning-level=DIAGNOSTIC_NAME:disabled指定された警告のみを抑制します。-Xsuppress-warning と同じように機能します。
-nowarn -Xwarning-level=DIAGNOSTIC_NAME:warning指定された警告を除き、すべての警告を抑制します。

警告をエラーに昇格

コマンド説明
-Werrorすべての警告をコンパイルエラーに昇格させます。
-Xwarning-level=DIAGNOSTIC_NAME:error指定された警告のみをエラーに昇格させます。
-Werror -Xwarning-level=DIAGNOSTIC_NAME:warning指定された警告を除き、すべての警告をエラーに昇格させます。

追加のコンパイラ警告の有効化

コマンド説明
-Wextraすべての追加の宣言、式、型コンパイラチェックを有効にし、trueの場合に警告を出力します。
-Xwarning-level=DIAGNOSTIC_NAME:warning指定された追加のコンパイラチェックのみを有効にします。
-Wextra -Xwarning-level=DIAGNOSTIC_NAME:disabled指定されたものを除き、すべての追加チェックを有効にします。

警告リスト

一般的なルールから除外したい警告が多数ある場合は、@argfile を介して別のファイルにリストできます。

フィードバックを残す

新しいコンパイラオプションはまだ実験的です。問題があれば、IssueトラッカーのYouTrackに報告してください。

Kotlin/JVM

インターフェース関数のデフォルトメソッド生成の変更

Kotlin 2.2.0-RC 以降、インターフェースで宣言された関数は、特に設定されていない限り、JVMのデフォルトメソッドとしてコンパイルされます。 この変更は、Kotlinのインターフェース関数が実装とともにバイトコードにコンパイルされる方法に影響します。 この動作は、非推奨の-Xjvm-defaultオプションに代わる新しい安定版コンパイラオプション-jvm-defaultによって制御されます。

-jvm-defaultオプションの動作は、次の値を使用して制御できます。

  • enable (デフォルト): インターフェースにデフォルトの実装を生成し、サブクラスとDefaultImplsクラスにブリッジ関数を含めます。このモードは、以前のKotlinバージョンとのバイナリ互換性を維持するために使用します。
  • no-compatibility: インターフェースにデフォルトの実装のみを生成します。このモードは互換性ブリッジとDefaultImplsクラスをスキップするため、新しいコードに適しています。
  • disable: インターフェースでのデフォルトの実装を無効にします。ブリッジ関数とDefaultImplsクラスのみが生成され、Kotlin 2.2.0-RC 以前の動作と一致します。

-jvm-defaultコンパイラオプションを設定するには、Gradle Kotlin DSLでjvmDefaultプロパティを設定します。

kotlin
kotlin {
  compilerOptions {
    jvmDefault = JvmDefaultMode.NO_COMPATIBILITY
  }
}

Kotlinメタデータにおけるアノテーションの読み書きのサポート

以前は、コンパイルされたJVMクラスファイルからリフレクションまたはバイトコード分析を使用してアノテーションを読み取り、シグネチャに基づいてメタデータエントリに手動で一致させる必要がありました。 このプロセスは、特にオーバーロードされた関数ではエラーが発生しやすかったのです。

現在、Kotlin 2.2.0-RC では、Kotlin Metadata JVMライブラリ がKotlinメタデータに格納されているアノテーションの読み取りをサポートするようになりました。

コンパイル済みファイルでメタデータ内のアノテーションを利用可能にするには、次のコンパイラオプションを追加します。

kotlin
-Xannotations-in-metadata

または、GradleビルドファイルのcompilerOptions {}ブロックに追加します。

kotlin
// build.gradle.kts
kotlin {
    compilerOptions {
        freeCompilerArgs.add("-Xannotations-in-metadata")
    }
}

このオプションを有効にすると、KotlinコンパイラはアノテーションをJVMバイトコードとともにメタデータに書き込み、kotlin-metadata-jvmライブラリからアクセスできるようにします。

このライブラリは、アノテーションにアクセスするための次のAPIを提供します。

  • KmClass.annotations
  • KmFunction.annotations
  • KmProperty.annotations
  • KmConstructor.annotations
  • KmPropertyAccessorAttributes.annotations
  • KmValueParameter.annotations
  • KmFunction.extensionReceiverAnnotations
  • KmProperty.extensionReceiverAnnotations
  • KmProperty.backingFieldAnnotations
  • KmProperty.delegateFieldAnnotations
  • KmEnumEntry.annotations

これらのAPIは実験的です。 オプトインするには、@OptIn(ExperimentalAnnotationsInMetadata::class)アノテーションを使用します。

Kotlinメタデータからアノテーションを読み取る例を次に示します。

kotlin
@file:OptIn(ExperimentalAnnotationsInMetadata::class)

import kotlin.metadata.ExperimentalAnnotationsInMetadata
import kotlin.metadata.jvm.KotlinClassMetadata

annotation class Label(val value: String)

@Label("Message class")
class Message

fun main() {
    val metadata = Message::class.java.getAnnotation(Metadata::class.java)
    val kmClass = (KotlinClassMetadata.readStrict(metadata) as KotlinClassMetadata.Class).kmClass
    println(kmClass.annotations)
    // [@Label(value = StringValue("Message class"))]
}

DANGER

プロジェクトでkotlin-metadata-jvmライブラリを使用している場合は、コードをテストしてアノテーションをサポートするように更新することをお勧めします。

そうしないと、将来のKotlinバージョンでメタデータ内のアノテーションがデフォルトで有効になったときに、プロジェクトが無効または不完全なメタデータを生成する可能性があります。

問題が発生した場合は、Issueトラッカー に報告してください。

Kotlin/Native

オブジェクトごとのメモリ割り当て

Kotlin/Nativeのメモリ割り当て機能が、オブジェクトごとにメモリを予約できるようになりました。場合によっては、厳密なメモリ制限やアプリケーション起動時の高いメモリ消費を回避するのに役立ちます。

この新機能は、デフォルトのアロケータの代わりにシステムメモリ割り当て機能を有効にする-Xallocator=stdコンパイラオプションを置き換えるように設計されています。これで、メモリ割り当て機能を切り替えることなく、バッファリング(割り当てのページング)を無効にできます。

この機能は現在実験的です。 これを有効にするには、gradle.propertiesファイルで次のオプションを設定します。

none
kotlin.native.binary.pagedAllocator=false

問題が発生した場合は、IssueトラッカーのYouTrackに報告してください。

LLVM 16から19へのアップデート

Kotlin 2.2.0-RC では、LLVMがバージョン16から19に更新されました。 新バージョンには、パフォーマンスの向上、バグ修正、セキュリティアップデートが含まれています。

このアップデートはコードに影響を与えないはずですが、何か問題が発生した場合は、Issueトラッカー に報告してください。

Kotlin/Wasm: wasmJsターゲットがjsターゲットから分離

以前は、wasmJsターゲットはjsターゲットと同じインフラストラクチャを共有していました。その結果、両方のターゲットは同じディレクトリ (build/js) にホストされ、同じNPMタスクと構成を使用していました。

現在、wasmJsターゲットはjsターゲットとは別の独自のインフラストラクチャを持っています。これにより、 Wasmのタスクと型がJavaScriptのものと区別され、独立した構成が可能になります。

さらに、Wasm関連のプロジェクトファイルとNPM依存関係は、build/wasmという別のディレクトリに配置されるようになりました。

新しいNPM関連タスクがWasm用に導入され、既存のJavaScriptタスクはJavaScript専用になりました。

WasmタスクJavaScriptタスク
kotlinWasmNpmInstallkotlinNpmInstall
wasmRootPackageJsonrootPackageJson

同様に、新しいWasm固有の宣言が導入されました。

Wasm宣言JavaScript宣言
WasmNodeJsRootPluginNodeJsRootPlugin
WasmNodeJsPluginNodeJsPlugin
WasmYarnPluginYarnPlugin
WasmNodeJsRootExtensionNodeJsRootExtension
WasmNodeJsEnvSpecNodeJsEnvSpec
WasmYarnRootEnvSpecYarnRootEnvSpec

これにより、JavaScriptターゲットとは独立してWasmターゲットを操作できるようになり、構成が簡素化されます。

この変更はデフォルトで有効になっており、追加の構成は必要ありません。

Kotlin/JS

@JsPlainObjectインターフェースにおけるcopy()の修正

Kotlin/JSにはjs-plain-objectsという実験的なプラグインがあり、@JsPlainObjectアノテーションが付けられたインターフェースにcopy()関数を導入しました。 copy()関数はオブジェクトを操作するために使用できます。

しかし、copy()の初期の実装は継承と互換性がなく、 @JsPlainObjectインターフェースが他のインターフェースを拡張する際に問題を引き起こしていました。

プレーンオブジェクトの制限を回避するため、copy()関数はオブジェクト自体からそのコンパニオンオブジェクトに移動されました。

kotlin
@JsPlainObject
external interface User {
    val name: String
    val age: Int
}

fun main() {
    val user = User(name = "SomeUser", age = 21)
    // This syntax is not valid anymore
    val copy = user.copy(age = 35)      
    // This is the correct syntax
    val copy = User.copy(user, age = 35)
}

この変更により、継承階層での競合が解決され、曖昧さが解消されます。 Kotlin 2.2.0-RC からデフォルトで有効になっています。

@JsModuleアノテーションを持つファイルにおけるtypealiasのサポート

以前は、JavaScriptモジュールから宣言をインポートするために@JsModuleアノテーションが付けられたファイルは、外部宣言のみに制限されていました。つまり、そのようなファイルではtypealiasを宣言できませんでした。

Kotlin 2.2.0-RC 以降、@JsModuleとマークされたファイル内でtypealiasを宣言できます。

kotlin
@file:JsModule("somepackage")
package somepackage
typealias SomeClass = Any

この変更により、Kotlin/JSの相互運用性の制限が緩和され、今後のリリースでさらに改善が計画されています。

@JsModuleを持つファイルにおけるtypealiasのサポートはデフォルトで有効になっています。

Gradle

Kotlin 2.2.0-RC はGradle 7.6.3から8.14まで完全に互換性があります。最新のGradleバージョンも使用できます。ただし、その場合は非推奨の警告が発生したり、一部の新しいGradle機能が動作しない可能性があることに注意してください。

Kotlin Gradleプラグインのコンソールでのリッチ出力のサポート

Kotlin 2.2.0-RC では、Gradleビルドプロセス中のコンソールでの色やその他のリッチ出力をサポートし、報告される診断を読みやすく、理解しやすくしました。 リッチ出力は、LinuxおよびmacOSでサポートされているターミナルエミュレータで利用できます。Windowsのサポートも現在開発中です。

Gradle console

この機能はデフォルトで有効になっていますが、オーバーライドしたい場合は、次のGradleプロパティをgradle.propertiesファイルに追加してください。

org.gradle.console=plain

このプロパティとそのオプションの詳細については、Gradleのドキュメントのログ形式のカスタマイズを参照してください。

KGP診断におけるProblems APIの統合

以前は、Kotlin Gradleプラグイン(KGP)は、警告やエラーなどの診断を、コンソールまたはログへのプレーンテキスト出力としてのみ報告していました。

2.2.0-RC から、KGPは追加のレポートメカニズムを導入しました。ビルドプロセス中に豊富で構造化された問題情報を報告するための標準化された方法であるGradleのProblems APIを使用するようになりました。

KGP診断は、Gradle CLIやIntelliJ IDEAなど、さまざまなインターフェースで読みやすく、より一貫して表示されるようになりました。

この統合は、Gradle 8.6以降からデフォルトで有効になっています。 APIはまだ進化中であるため、最新の改善の恩恵を受けるには、最新のGradleバージョンを使用してください。

KGPと--warning-modeの互換性

Kotlin Gradleプラグイン(KGP)の診断は、固定された深刻度レベルを使用して問題を報告していたため、Gradleの--warning-modeコマンドラインオプションは、KGPがエラーを表示する方法に影響を与えませんでした。

現在、KGP診断は--warning-modeオプションと互換性があり、より高い柔軟性を提供します。たとえば、 すべての警告をエラーに変換したり、警告を完全に無効にしたりできます。

この変更により、KGP診断は選択された警告モードに基づいて出力を調整します。

  • --warning-mode=failを設定すると、Severity.Warningの診断はSeverity.Errorに昇格されます。
  • --warning-mode=noneを設定すると、Severity.Warningの診断はログに記録されません。

この動作はKotlin 2.2.0-RC 以降、デフォルトで有効になっています。

--warning-modeオプションを無視するには、Gradleプロパティでkotlin.internal.diagnostics.ignoreWarningMode=trueを設定します。

Kotlin標準ライブラリ: Base64およびHexFormat APIの安定版

Kotlin 2.2.0-RC では、Base64 API および HexFormat API安定版になりました。

Base64エンコーディングとデコーディング

Kotlin 1.8.20でBase64エンコーディングとデコーディングの実験的サポートが導入されました。 Kotlin 2.2.0-RC では、Base64 API が安定版になり、 このリリースで追加された新しいBase64.Pemを含む4つのエンコーディングスキームが含まれています。

  • Base64.Default は、標準のBase64エンコーディングスキームを使用します。

    TIP

    Base64.DefaultBase64クラスのコンパニオンオブジェクトです。

    その結果、Base64.Default.encode()Base64.Default.decode()の代わりに、Base64.encode()Base64.decode()でその関数を呼び出すことができます。

  • Base64.UrlSafe は、「URLおよびファイル名に安全な」エンコーディングスキームを使用します。

  • Base64.MimeMIMEエンコーディングスキームを使用し、エンコーディング時に76文字ごとに改行記号を挿入し、デコーディング時に不正な文字をスキップします。

  • Base64.PemBase64.Mimeのようにデータをエンコードしますが、行の長さを64文字に制限します。

Base64 APIを使用して、バイナリデータをBase64文字列にエンコードしたり、バイトにデコードし直したりできます。

例を次に示します。

kotlin
val foBytes = "fo".map { it.code.toByte() }.toByteArray()
Base64.Default.encode(foBytes) // "Zm8="
// Alternatively:
// Base64.encode(foBytes)

val foobarBytes = "foobar".map { it.code.toByte() }.toByteArray()
Base64.UrlSafe.encode(foobarBytes) // "Zm9vYmFy"

Base64.Default.decode("Zm8=") // foBytes
// Alternatively:
// Base64.decode("Zm8=")

Base64.UrlSafe.decode("Zm9vYmFy") // foobarBytes

JVMでは、入力ストリームと出力ストリームでBase64をエンコードおよびデコードするために、.encodingWith()および.decodingWith()拡張関数を使用します。

kotlin
import kotlin.io.encoding.*
import java.io.ByteArrayOutputStream

fun main() {
    val output = ByteArrayOutputStream()
    val base64Output = output.encodingWith(Base64.Default)

    base64Output.use { stream ->
        stream.write("Hello World!!".encodeToByteArray())
    }

    println(output.toString())
    // SGVsbG8gV29ybGQhIQ==
}

HexFormat APIによる16進数のパースとフォーマット

Kotlin 1.9.0で導入されたHexFormat API安定版になりました。 これを使用して、数値と16進数文字列の間で変換できます。

例:

kotlin
fun main() {
    println(93.toHexString())
}

詳細については、新しいHexFormatクラスによる16進数のフォーマットとパース を参照してください。