Skip to content

Kotlin 2.2.0 の新機能

2025年6月23日リリース

Kotlin 2.2.0 がリリースされました!主なハイライトは以下の通りです:

Kotlin 言語進化(Language Evolution)チームが新機能について議論し、質問に答えているこちらの動画もご覧いただけます:

Kotlin のリリースサイクルに関する情報は、Kotlin のリリースプロセス を参照してください。

IDE サポート

2.2.0 をサポートする Kotlin プラグインは、IntelliJ IDEA および Android Studio の最新バージョンにバンドルされています。IDE で Kotlin プラグインを個別にアップデートする必要はありません。ビルドスクリプト内の Kotlin バージョンを 2.2.0 に変更 するだけで利用可能です。

詳細は 新しいリリースへのアップデート を参照してください。

言語

本リリースでは、ガード条件、非ローカルな breakcontinue、およびマルチダラー補間が Stable(安定版)昇格 しました。さらに、コンテキストパラメータコンテキスト依存の解決 など、いくつかの機能がプレビューとして導入されました。

Experimental

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

コンテキストパラメータ(context parameters)を使用すると、関数やプロパティが、周囲のコンテキストで暗黙的に利用可能な依存関係を宣言できるようになります。

コンテキストパラメータを使用すると、一連の関数呼び出しの間で共有され、めったに変更されないサービスや依存関係などの値を、手動で受け渡す必要がなくなります。

コンテキストパラメータは、コンテキストレシーバー(context receivers)と呼ばれていた古い実験的な機能を置き換えるものです。コンテキストレシーバーからコンテキストパラメータへの移行については、ブログ投稿 で説明されている IntelliJ IDEA のアシスト機能を利用できます。

主な違いは、コンテキストパラメータは関数の本体にレシーバーとして導入されない点です。そのため、コンテキストが暗黙的に利用可能だったコンテキストレシーバーとは異なり、コンテキストパラメータのメンバーにアクセスするには、そのパラメータ名を使用する必要があります。

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

コンテキストパラメータを宣言する方法

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

kotlin
// UserService はコンテキストで必要とされる依存関係を定義します
interface UserService {
    fun log(message: String)
    fun findUserById(id: Int): String
}

// コンテキストパラメータを持つ関数を宣言します
context(users: UserService)
fun outputMessage(message: String) {
    // コンテキストの log を使用します
    users.log("Log: $message")
}

// コンテキストパラメータを持つプロパティを宣言します
context(users: UserService)
val firstUser: String
    // コンテキストの findUserById を使用します    
    get() = users.findUserById(1)

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

kotlin
// "_" をコンテキストパラメータ名として使用します
context(_: UserService)
fun logWelcome() {
    // UserService から適切な log 関数を見つけます
    outputMessage("Welcome!")
}

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

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

Bash
-Xcontext-parameters

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

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

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

フィードバックのお願い

この機能は、将来の Kotlin リリースで安定化および改善される予定です。問題トラッカー YouTrack へのフィードバックをお待ちしております。

Experimental

コンテキスト依存の解決のプレビュー

Kotlin 2.2.0 では、コンテキスト依存の解決(context-sensitive resolution)の実装がプレビューとして導入されました。

この機能の概要については、こちらの動画をご覧ください:

これまでは、コンテキストから型が推論できる場合でも、列挙型(enum)のエントリやシールクラス(sealed class)のメンバーのフルネームを記述する必要がありました。例えば:

kotlin
enum class Problem {
    CONNECTION, AUTHENTICATION, DATABASE, UNKNOWN
}

fun message(problem: Problem): String = when (problem) {
    Problem.CONNECTION -> "connection"
    Problem.AUTHENTICATION -> "authentication"
    Problem.DATABASE -> "database"
    Problem.UNKNOWN -> "unknown"
}

コンテキスト依存の解決を使用すると、期待される型がわかっているコンテキストでは型名を省略できるようになります:

kotlin
enum class Problem {
    CONNECTION, AUTHENTICATION, DATABASE, UNKNOWN
}

// problem の既知の型に基づいて enum エントリを解決します
fun message(problem: Problem): String = when (problem) {
    CONNECTION -> "connection"
    AUTHENTICATION -> "authentication"
    DATABASE -> "database"
    UNKNOWN -> "unknown"
}

コンパイラはこのコンテキスト上の型情報を使用して、正しいメンバーを解決します。この情報には、特に以下が含まれます:

  • when 式の対象
  • 明示的な戻り値の型
  • 宣言された変数型
  • 型チェック (is) およびキャスト (as)
  • シールクラス階層の既知の型
  • パラメータの宣言された型

コンテキスト依存の解決は、関数、パラメータを持つプロパティ、またはレシーバーを持つ拡張プロパティには適用されません。

プロジェクトでコンテキスト依存の解決を試すには、コマンドラインで以下のコンパイラオプションを使用します:

bash
-Xcontext-sensitive-resolution

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

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

この機能は将来の Kotlin リリースで安定化および改善する予定です。問題トラッカー YouTrack へのフィードバックをお待ちしております。

Experimental

アノテーション使用箇所ターゲットに関する機能のプレビュー

Kotlin 2.2.0 では、アノテーションの 使用箇所ターゲット (use-site targets) をより便利に扱えるようにするいくつかの機能が導入されました。

Experimental

プロパティ向けの `@all` メタターゲット

Kotlin では、宣言の特定の部分にアノテーションを付加することができ、これは 使用箇所ターゲット として知られています。しかし、各ターゲットに個別にアノテーションを付けるのは複雑で間違いやすいものでした:

kotlin
data class User(
    val username: String,

    @param:Email      // コンストラクタパラメータ
    @field:Email      // バッキングフィールド
    @get:Email        // ゲッターメソッド
    @property:Email   // Kotlin プロパティ参照
    val email: String,
) {
    @field:Email
    @get:Email
    @property:Email
    val secondaryEmail: String? = null
}

これを簡素化するため、Kotlin はプロパティ向けの新しい @all メタターゲットを導入しました。この機能は、プロパティのすべての関連部分にアノテーションを適用するようコンパイラに指示します。@all を使用すると、コンパイラは以下の部分へのアノテーション適用を試みます:

  • param: プライマリコンストラクタで宣言されている場合、そのコンストラクタパラメータ。

  • property: Kotlin プロパティ自体。

  • field: バッキングフィールドが存在する場合、そのフィールド。

  • get: ゲッターメソッド。

  • setparam: プロパティが var として定義されている場合、そのセッターメソッドのパラメータ。

  • RECORD_COMPONENT: クラスが @JvmRecord の場合、アノテーションは Java レコードコンポーネント に適用されます。この動作は、Java がレコードコンポーネント上のアノテーションを処理する方法を模倣しています。

コンパイラは、指定されたプロパティのターゲットに対してのみアノテーションを適用します。

以下の例では、@Email アノテーションが各プロパティのすべての関連ターゲットに適用されます:

kotlin
data class User(
    val username: String,

    // @Email を param, property, field,
    // get, および setparam (var の場合) に適用します
    @all:Email val email: String,
) {
    // @Email を property, field, および get に適用します
    // (コンストラクタに含まれないため param はありません)
    @all:Email val secondaryEmail: String? = null
}

@all メタターゲットは、プライマリコンストラクタ内および外のすべてのプロパティで使用できます。ただし、@all メタターゲットを 複数のアノテーション と併用することはできません。

この新機能により構文が簡素化され、一貫性が確保され、Java レコードとの相互運用性が向上します。

プロジェクトで @all メタターゲットを有効にするには、コマンドラインで以下のコンパイラオプションを使用します:

Bash
-Xannotation-target-all

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

kotlin
// build.gradle.kts
kotlin {
    compilerOptions {
        freeCompilerArgs.add("-Xannotation-target-all")
    }
}

この機能はプレビュー段階です。問題が発生した場合は、問題トラッカー YouTrack に報告してください。@all メタターゲットの詳細については、この KEEP プロポーザルを参照してください。

Experimental

使用箇所アノテーションターゲットの新しいデフォルトルール

Kotlin 2.2.0 では、アノテーションをパラメータ、フィールド、プロパティに伝播させるための新しいデフォルトルールが導入されました。これまでは、アノテーションはデフォルトで parampropertyfield のいずれか一つにしか適用されませんでしたが、新しいデフォルトではアノテーションに期待される動作により即したものになります。

適用可能なターゲットが複数ある場合、以下のように一つ以上が選択されます:

  • コンストラクタパラメータターゲット (param) が適用可能な場合、それが使用されます。
  • プロパティターゲット (property) が適用可能な場合、それが使用されます。
  • property が適用可能でなく、フィールドターゲット (field) が適用可能な場合、field が使用されます。

複数のターゲットがあり、parampropertyfield のいずれも適用可能でない場合、アノテーションはエラーになります。

この機能を有効にするには、Gradle ビルドファイルの compilerOptions {} ブロックに以下を追加します:

kotlin
// build.gradle.kts
kotlin {
    compilerOptions {
        freeCompilerArgs.add("-Xannotation-default-target=param-property")
    }
}

または、コンパイラのコマンドライン引数を使用します:

Bash
-Xannotation-default-target=param-property

古い動作を使用したい場合は、いつでも以下のように対応できます:

  • 特定のケースでは、@Annotation の代わりに @param:Annotation を使用するなど、必要なターゲットを明示的に定義します。

  • プロジェクト全体では、Gradle ビルドファイルで以下のフラグを使用します:

    kotlin
    // build.gradle.kts
    kotlin {
        compilerOptions {
            freeCompilerArgs.add("-Xannotation-default-target=first-only")
        }
    }

この機能はプレビュー段階です。問題が発生した場合は、問題トラッカー YouTrack に報告してください。使用箇所アノテーションターゲットの新しいデフォルトルールの詳細については、この KEEP プロポーザルを参照してください。

Beta

ネストされた型エイリアスのサポート

Kotlin 2.2.0 では、他の宣言の内部で型エイリアスを定義できるようになりました。

この機能の概要については、こちらの動画をご覧ください:

これまでは、型エイリアス (type aliases) は Kotlin ファイルのトップレベルでしか宣言できませんでした。これは、内部的なものやドメイン固有の型エイリアスであっても、それらが使用されるクラスの外に配置しなければならないことを意味していました。

2.2.0 からは、外側のクラスから型パラメータをキャプチャしない限り、他の宣言の内部で型エイリアスを定義できるようになります:

kotlin
class Dijkstra {
    typealias VisitedNodes = Set<Node>

    private fun step(visited: VisitedNodes, ...) = ...
}

ネストされた型エイリアスには、型パラメータに言及できないなどのいくつかの追加の制約があります。ルールの全セットについては ドキュメント を確認してください。

ネストされた型エイリアスを使用すると、カプセル化が改善され、パッケージレベルの煩雑さが軽減され、内部実装が簡素化されるため、よりクリーンで保守性の高いコードを作成できます。

ネストされた型エイリアスを有効にする方法

プロジェクトでネストされた型エイリアスを有効にするには、コマンドラインで以下のコンパイラオプションを使用します:

bash
-Xnested-type-aliases

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

kotlin
// build.gradle.kts
kotlin {
    compilerOptions {
        freeCompilerArgs.add("-Xnested-type-aliases")
    }
}

フィードバックのお願い

ネストされた型エイリアスは現在 Beta(ベータ) です。問題が発生した場合は、問題トラッカー YouTrack に報告してください。この機能の詳細については、この KEEP プロポーザルを参照してください。

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

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

Kotlin 言語設計機能とプロポーザルの全リストを見る

Experimental

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

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

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

新しいソリューションを使用すると、一般的なルールを上書きしたり、特定の診断を排除したりすることが、一貫した方法で行えるようになります。

適用方法

新しいコンパイラオプションの構文は以下の通りです:

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

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

ユースケース

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

警告を抑制する

コマンド説明
-nowarnコンパイル中の全ての警告を抑制します。
-Xwarning-level=DIAGNOSTIC_NAME:disabled指定された警告のみを抑制します。
-nowarn -Xwarning-level=DIAGNOSTIC_NAME:warning指定された警告以外の全ての警告を抑制します。

警告をエラーに格上げする

コマンド説明
-Werror全ての警告をコンパイルエラーに格上げします。
-Xwarning-level=DIAGNOSTIC_NAME:error指定された警告のみをエラーに格上げします。
-Werror -Xwarning-level=DIAGNOSTIC_NAME:warning指定された警告以外の全ての警告をエラーに格上げします。

追加のコンパイラ警告を有効にする

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

警告リスト

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

フィードバックのお願い

この新しいコンパイラオプションはまだ Experimental(実験的) です。問題が発生した場合は、問題トラッカー YouTrack に報告してください。

Kotlin/JVM

Kotlin 2.2.0 では JVM 向けに多くのアップデートが行われました。コンパイラが Java 24 バイトコードをサポートするようになり、インターフェース関数のデフォルトメソッド生成に変更が導入されました。本リリースでは、Kotlin メタデータ内のアノテーションの操作も簡素化され、インライン値クラスによる Java との相互運用性が向上し、JVM レコードへのアノテーション付加のサポートも改善されました。

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

Kotlin 2.2.0 以降、インターフェースで宣言された関数は、別途設定されていない限り JVM デフォルトメソッドとしてコンパイルされます。 この変更は、実装を持つ Kotlin のインターフェース関数がバイトコードにコンパイルされる方法に影響します。

この動作は、非推奨となった -Xjvm-default オプションに代わる、新しい安定したコンパイラオプション -jvm-default によって制御されます。

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

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

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

kotlin
// build.gradle.kts
kotlin {
    compilerOptions {
        jvmDefault = JvmDefaultMode.NO_COMPATIBILITY
    }
}
Experimental

Kotlin メタデータ内のアノテーションの読み書きのサポート

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

Kotlin 2.2.0 では、 に 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 は Experimental(実験的) です。 オプトインするには、@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"))]
}

プロジェクトで kotlin-metadata-jvm ライブラリを使用している場合は、アノテーションをサポートするようにコードをテストおよび更新することをお勧めします。 そうしないと、将来の Kotlin バージョンでメタデータ内のアノテーションが デフォルトで有効 になった際に、プロジェクトが不正確または不完全なメタデータを生成する可能性があります。

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

Experimental

インライン値クラスによる Java 相互運用性の向上

Kotlin 2.2.0 では、新しい実験的なアノテーション @JvmExposeBoxed が導入されました。このアノテーションを使用すると、Java から インライン値クラス(inline value classes) を利用しやすくなります。

この機能の概要については、こちらの動画をご覧ください:

デフォルトでは、Kotlin はインライン値クラスをコンパイルして アンボックス化された表現(unboxed representations) を使用します。これはパフォーマンスに優れていますが、Java からの使用は困難、あるいは不可能な場合が多いです。例えば:

kotlin
@JvmInline value class PositiveInt(val number: Int) {
    init { require(number >= 0) }
}

この場合、クラスがアンボックス化されているため、Java が呼び出せるコンストラクタが存在しません。また、Java が init ブロックをトリガーして number が正であることを保証する方法もありません。

クラスに @JvmExposeBoxed アノテーションを付けると、Kotlin は Java が直接呼び出せる公開コンストラクタを生成し、init ブロックも確実に実行されるようにします。

@JvmExposeBoxed アノテーションをクラス、コンストラクタ、または関数レベルで適用して、Java に公開する内容を細かく制御できます。

例えば、以下のコードでは、拡張関数 .timesTwoBoxed() は Java からアクセス できません

kotlin
@JvmInline
value class MyInt(val value: Int)

fun MyInt.timesTwoBoxed(): MyInt = MyInt(this.value * 2)

Java コードから MyInt クラスのインスタンスを作成し、.timesTwoBoxed() 関数を呼び出せるようにするには、クラスと関数の両方に @JvmExposeBoxed アノテーションを追加します:

kotlin
@JvmExposeBoxed
@JvmInline
value class MyInt(val value: Int)

@JvmExposeBoxed
fun MyInt.timesTwoBoxed(): MyInt = MyInt(this.value * 2)

これらのアノテーションにより、Kotlin コンパイラは MyInt クラスに対して Java からアクセス可能なコンストラクタを生成します。また、値クラスのボックス化された形式を使用する拡張関数のオーバーロードも生成します。その結果、以下の Java コードが正常に動作します:

java
MyInt input = new MyInt(5);
MyInt output = ExampleKt.timesTwoBoxed(input);

公開したいインライン値クラスの各部分に個別にアノテーションを付けたくない場合は、モジュール全体に実質的にアノテーションを適用できます。モジュールにこの動作を適用するには、-Xjvm-expose-boxed オプションを付けてコンパイルします。このオプションを使用してコンパイルすることは、モジュール内のすべての宣言に @JvmExposeBoxed アノテーションがあるかのように扱うのと同じ効果があります。

この新しいアノテーションは、Kotlin が内部的に値クラスをコンパイルまたは使用する方法を変更するものではなく、既存のコンパイル済みコードはすべて有効なままです。単に Java との相互運用性を向上させるための新しい機能を追加するだけです。値クラスを使用する Kotlin コードのパフォーマンスへの影響はありません。

@JvmExposeBoxed アノテーションは、メンバー関数のボックス化されたバリアントを公開し、ボックス化された戻り値の型を受け取りたいライブラリ作成者にとって便利です。これにより、インライン値クラス(効率的だが Kotlin 専用)とデータクラス(Java と互換性があるが常にボックス化される)のどちらかを選択する必要がなくなります。

@JvmExposeBoxed アノテーションがどのように機能し、どのような問題を解決するかについての詳細は、この KEEP プロポーザルを参照してください。

JVM レコードへのアノテーション付加のサポート改善

Kotlin は Kotlin 1.5.0 から JVM レコード(JVM records) をサポートしています。Kotlin 2.2.0 では、特に Java の RECORD_COMPONENT ターゲットに関して、レコードコンポーネント上のアノテーションの処理方法が改善されました。

まず、RECORD_COMPONENT をアノテーションターゲットとして使用したい場合は、Kotlin (@Target) と Java の両方のアノテーションを手動で追加する必要があります。これは、Kotlin の @Target アノテーションが RECORD_COMPONENT をサポートしていないためです。例えば:

kotlin
@Target(AnnotationTarget.CLASS, AnnotationTarget.PROPERTY)
@java.lang.annotation.Target(ElementType.CLASS, ElementType.RECORD_COMPONENT)
annotation class exampleClass

両方のリストを手動で維持するのは間違いやすいため、Kotlin 2.2.0 では Kotlin と Java のターゲットが一致しない場合にコンパイラ警告を出すようになりました。例えば、Java ターゲットリストに ElementType.CLASS が欠けている場合、コンパイラは以下を報告します:

Incompatible annotation targets: Java target 'CLASS' missing, corresponding to Kotlin targets 'CLASS'.

次に、レコード内のアノテーション伝播に関して、Kotlin の動作は Java と異なります。Java では、レコードコンポーネント上のアノテーションは、自動的にバッキングフィールド、ゲッター、およびコンストラクタパラメータに適用されます。Kotlin はデフォルトではこれを行いませんが、@all: 使用箇所ターゲット を使用してこの動作を再現できるようになりました。

例えば:

kotlin
@JvmRecord
data class Person(val name: String, @all:Positive val age: Int)

@JvmRecord@all: を併用すると、Kotlin は以下のようになります:

  • アノテーションをプロパティ、バッキングフィールド、コンストラクタパラメータ、およびゲッターに伝播させます。
  • アノテーションが Java の RECORD_COMPONENT をサポートしている場合、レコードコンポーネントにもアノテーションを適用します。

Kotlin/Native

2.2.0 以降、Kotlin/Native は LLVM 19 を使用します。本リリースでは、メモリ消費を追跡・調整するために設計されたいくつかの実験的な機能も導入されています。

Experimental

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

Kotlin/Native の メモリ割り当てツール(memory allocator) が、オブジェクトごとにメモリを予約できるようになりました。特定のケースでは、厳しいメモリ制限を満たしたり、アプリケーション起動時のメモリ消費を抑えたりするのに役立ちます。

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

この機能は現在 Experimental(実験的) です。 有効にするには、gradle.properties ファイルに以下のオプションを設定してください:

none
kotlin.native.binary.pagedAllocator=false

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

Experimental

ランタイムでの Latin-1 エンコード文字列のサポート

JVM と同様に、Kotlin が Latin-1 エンコード文字列をサポートするようになりました。これにより、アプリケーションのバイナリサイズを縮小し、メモリ消費を調整するのに役立ちます。

デフォルトでは、Kotlin の文字列は各文字を 2 バイトで表す UTF-16 エンコーディングを使用して保存されます。場合によっては、ソースコードと比較してバイナリ内の文字列が 2 倍のスペースを占めたり、単純な ASCII ファイルからデータを読み込む際にディスク上のファイル保存の 2 倍のメモリを消費したりすることがあります。

一方、Latin-1 (ISO 8859-1) エンコーディングは、最初の 256 個の Unicode 文字のそれぞれをわずか 1 バイトで表します。Latin-1 サポートが有効な場合、文字列のすべての文字がその範囲内に収まる限り、文字列は Latin-1 エンコーディングで保存されます。それ以外の場合は、デフォルトの UTF-16 エンコーディングが使用されます。

Latin-1 サポートを有効にする方法

この機能は現在 Experimental(実験的) です。 有効にするには、gradle.properties ファイルに以下のオプションを設定してください:

none
kotlin.native.binary.latin1Strings=true

既知の問題

この機能が実験段階である間は、cinterop 拡張関数の String.pinString.usePinned、および String.refTo の効率が低下します。これらの各呼び出しにより、UTF-16 への自動文字列変換がトリガーされる可能性があります。

Kotlin チームは、Google の同僚、特にこの機能を実装してくれた Sonya Valchuk 氏に深く感謝します。

Kotlin でのメモリ消費に関する詳細は、ドキュメント を参照してください。

Apple プラットフォームでのメモリ消費の追跡改善

Kotlin 2.2.0 以降、Kotlin コードによって割り当てられたメモリにタグが付けられるようになりました。これにより、Apple プラットフォームでのメモリ問題のデバッグに役立ちます。

アプリケーションの高いメモリ使用量を調査する際に、Kotlin コードによってどれだけのメモリが予約されているかを特定できるようになりました。Kotlin の共有分には識別子がタグ付けされ、Xcode Instruments の VM Tracker などのツールを通じて追跡できます。

この機能はデフォルトで有効になっていますが、以下の条件が すべて 満たされている場合にのみ、Kotlin/Native デフォルトメモリアロケータで利用可能です:

  • タグ付けが有効であること。メモリには有効な識別子がタグ付けされている必要があります。Apple は 240 から 255 の間の数字を推奨しており、デフォルト値は 246 です。

    kotlin.native.binary.mmapTag=0 Gradle プロパティを設定すると、タグ付けは無効になります。

  • mmap による割り当て。アロケータは mmap システムコールを使用してファイルをメモリにマップする必要があります。

    kotlin.native.binary.disableMmap=true Gradle プロパティを設定すると、デフォルトのアロケータは mmap の代わりに malloc を使用します。

  • ページングが有効であること。割り当てのページング(バッファリング)が有効である必要があります。

    kotlin.native.binary.pagedAllocator=false Gradle プロパティを設定すると、メモリはオブジェクトごとに予約されます。

Kotlin でのメモリ消費に関する詳細は、ドキュメント を参照してください。

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

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

このアップデートによってコードに影響が出ることはありませんが、問題が発生した場合は 問題トラッカー に報告してください。

Windows 7 ターゲットの非推奨化

Kotlin 2.2.0 以降、サポートされる Windows の最小バージョンが Windows 7 から Windows 10 に引き上げられました。Microsoft が 2025 年 1 月に Windows 7 のサポートを終了したため、このレガシーターゲットを非推奨にすることを決定しました。

詳細については、 を参照してください。

Kotlin/Wasm

本リリースでは、Wasm ターゲットのビルドインフラストラクチャが JavaScript ターゲットから分離されました。さらに、Binaryen ツールをプロジェクトまたはモジュールごとに設定できるようになりました。

Wasm ターゲット의 ビルドインフラストラクチャを JavaScript ターゲットから分離

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

今回、wasmJs ターゲットは js ターゲットから独立した独自のインフラストラクチャを持つようになりました。これにより、Wasm のタスクと型を JavaScript のものと区別でき、独立した設定が可能になります。

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

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

Wasm タスクJavaScript タスク
kotlinWasmNpmInstallkotlinNpmInstall
wasmRootPackageJsonrootPackageJson

同様に、新しい Wasm 固有の宣言が追加されました:

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

JavaScript ターゲットから独立して Wasm ターゲットを扱えるようになり、設定プロセスが簡素化されます。

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

プロジェクトごとの Binaryen 設定

Kotlin/Wasm で プロダクションビルドを最適化 するために使用される Binaryen ツールは、以前はルートプロジェクトで一度だけ設定されていました。

今回、Binaryen ツールをプロジェクトまたはモジュールごとに設定できるようになりました。この変更は Gradle のベストプラティスに沿ったもので、プロジェクト分離(project isolation) などの機能のより良いサポートを保証し、複雑なビルドにおけるビルドパフォーマンスと信頼性を向上させます。

さらに、必要に応じてモジュールごとに異なるバージョンの Binaryen を設定することも可能になりました。

この機能はデフォルトで有効になっています。ただし、Binaryen のカスタム設定を行っている場合は、ルートプロジェクトだけでなく、プロジェクトごとに適用する必要があります。

Kotlin/JS

本リリースでは、@JsPlainObject インターフェースの copy() 関数@JsModule アノテーションを持つファイル内の型エイリアス、およびその他の 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)
    // この構文は無効になりました
    val copy = user.copy(age = 35)      
    // これが正しい構文です
    val copy = User.copy(user, age = 35)
}

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

@JsModule アノテーションを持つファイルでの型エイリアスのサポート

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

Kotlin 2.2.0 以降、@JsModule が付いたファイル内でも型エイリアスを宣言できるようになりました:

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

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

@JsModule を持つファイルでの型エイリアスのサポートは、デフォルトで有効です。

マルチプラットフォームの expect 宣言における @JsExport のサポート

Kotlin Multiplatform プロジェクトで expect/actual メカニズム を使用する際、共通(common)コードの expect 宣言に対して @JsExport アノテーションを使用することはできませんでした。

本リリースから、expect 宣言に直接 @JsExport を適用できるようになりました:

kotlin
// commonMain

// 以前はエラーでしたが、正しく動作するようになりました
@JsExport
expect class WindowManager {
    fun close()
}

@JsExport
fun acceptWindowManager(manager: WindowManager) {
    ...
}

// jsMain

@JsExport
actual class WindowManager {
    fun close() {
        window.close()
    }
}

JavaScript ソースセットの対応する actual 実装にも @JsExport を付ける必要があり、エクスポート可能な型のみを使用する必要があります。

この修正により、commonMain で定義された共有コードを JavaScript に正しくエクスポートできるようになります。手動の回避策を使用することなく、マルチプラットフォームコードを JavaScript 利用者に公開できるようになりました。

この変更はデフォルトで有効です。

Promise<Unit> 型での @JsExport の使用が可能に

以前は、@JsExport アノテーションを付けて Promise<Unit> 型を返す関数をエクスポートしようとすると、Kotlin コンパイラがエラーを出していました。

Promise<Int> などの戻り値の型は正しく機能していましたが、Promise<Unit> を使用すると、TypeScript では正しく Promise<void> にマップされるにもかかわらず、「エクスポート不可能な型(non-exportable type)」という警告が表示されていました。

この制限は解除されました。現在、以下のコードはエラーなくコンパイルされます:

kotlin
// 以前から正しく動作していたもの
@JsExport
fun fooInt(): Promise<Int> = GlobalScope.promise {
    delay(100)
    return@promise 42
}

// 以前はエラーでしたが、正しく動作するようになりました
@JsExport
fun fooUnit(): Promise<Unit> = GlobalScope.promise {
    delay(100)
}

この変更により、Kotlin/JS 相互運用モデルにおける不必要な制限が取り除かれました。この修正はデフォルトで有効です。

Gradle

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

本リリースでは、Kotlin Gradle プラグインの診断機能にいくつかの改善が行われました。 また、バイナリ互換性検証(binary compatibility validation) の実験的な統合が導入され、ライブラリの開発が容易になりました。

Experimental

Kotlin Gradle プラグインに含まれるバイナリ互換性検証

ライブラリのバージョン間でのバイナリ互換性のチェックを容易にするため、バイナリ互換性検証ツール(binary compatibility validator) の機能を Kotlin Gradle プラグイン (KGP) に移行する実験を行っています。小規模なプロジェクトで試すことは可能ですが、まだ本番環境での使用はお勧めしません。

オリジナルの バイナリ互換性検証ツール は、この実験フェーズ中も引き続きメンテナンスされます。

Kotlin ライブラリは、JVM クラスファイルまたは klib の 2 つのバイナリ形式のいずれかを使用できます。これらの形式には互換性がないため、KGP はそれぞれを個別に処理します。

バイナリ互換性検証機能を有効にするには、build.gradle.kts ファイルの kotlin{} ブロックに以下を追加します:

kotlin
// build.gradle.kts
kotlin {
    @OptIn(org.jetbrains.kotlin.gradle.dsl.abi.ExperimentalAbiValidation::class)
    abiValidation {
        // 古いバージョンの Gradle との互換性を確保するために set() 関数を使用します
        enabled.set(true)
    }
}

プロジェクトにバイナリ互換性をチェックしたいモジュールが複数ある場合は、各モジュールで個別に設定してください。各モジュールは独自のカスタム設定を持つことができます。

有効にしたら、checkLegacyAbi Gradle タスクを実行してバイナリ互換性の問題をチェックします。IntelliJ IDEA 内で、またはプロジェクトディレクトリのコマンドラインからタスクを実行できます:

kotlin
./gradlew checkLegacyAbi

このタスクは、現在のコードからアプリケーション・バイナリ・インターフェース (ABI) ダンプを UTF-8 テキストファイルとして生成します。 次に、新しいダンプを前のリリースのものと比較します。差異が見つかった場合、タスクはそれらをエラーとして報告します。エラーを確認し、変更が許容範囲内であると判断した場合は、updateLegacyAbi Gradle タスクを実行して参照 ABI ダンプを更新できます。

クラスのフィルタリング

この機能では、ABI ダンプ内のクラスをフィルタリングできます。名前または部分一致する名前、あるいはそれらをマークするアノテーション(またはアノテーション名の一部)によって、クラスを明示的に含めたり除外したりできます。

例えば、このサンプルは com.company パッケージ内のすべてのクラスを除外します:

kotlin
// build.gradle.kts
kotlin {
    @OptIn(org.jetbrains.kotlin.gradle.dsl.abi.ExperimentalAbiValidation::class)
    abiValidation {
        filters.excluded.byNames.add("com.company.**")
    }
}

バイナリ互換性検証ツールの設定についての詳細は、KGP API リファレンス を参照してください。

マルチプラットフォームにおける制限事項

マルチプラットフォームプロジェクトにおいて、ホストがすべてのターゲットのクロスコンパイルをサポートしていない場合、KGP は他のターゲットの ABI ダンプをチェックすることで、サポートされていないターゲットの ABI 変更を推測しようとします。このアプローチにより、後で すべての ターゲットをコンパイルできるホストに切り替えたときに、誤った検証失敗が発生するのを防ぐことができます。

build.gradle.kts ファイルに以下を追加することで、KGP がサポートされていないターゲットの ABI 変更を推測しないようにデフォルトの動作を変更できます:

kotlin
// build.gradle.kts
kotlin {
    @OptIn(org.jetbrains.kotlin.gradle.dsl.abi.ExperimentalAbiValidation::class)
    abiValidation {
        klib {
            keepUnsupportedTargets = false
        }
    }
}

ただし、プロジェクトにサポートされていないターゲットがある場合、タスクが ABI ダンプを作成できないため、checkLegacyAbi タスクの実行は失敗します。他のターゲットからの推測によって互換性のない変更を見逃すよりも、チェックを失敗させることの方が重要な場合は、この動作が望ましいかもしれません。

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

Kotlin 2.2.0 では、Gradle ビルドプロセス中のコンソールでカラーなどのリッチ出力をサポートし、報告される診断結果を読みやすく理解しやすくしました。

リッチ出力は、Linux および macOS のサポートされているターミナルエミュレータで利用可能です。Windows へのサポートも現在進めています。

Gradle コンソール

この機能はデフォルトで有効になっていますが、上書きしたい場合は、gradle.properties ファイルに以下の Gradle プロパティを追加してください:

org.gradle.console=plain

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

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

以前、Kotlin Gradle Plugin (KGP) は、警告やエラーなどの診断情報をコンソールやログにプレーンテキストとして出力することしかできませんでした。

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

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

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

--warning-mode との KGP の互換性

これまでの Kotlin Gradle Plugin (KGP) の診断では、固定された重大度レベルを使用して問題をレポートしていたため、Gradle の --warning-mode コマンドラインオプション は KGP のエラー表示に影響を与えませんでした。

今回、KGP の診断が --warning-mode オプションに対応し、より柔軟性が増しました。例えば、すべての警告をエラーに変換したり、警告を完全に無効にしたりできます。

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

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

この動作は、2.2.0 からデフォルトで有効になります。

--warning-mode オプションを無視するには、gradle.properties ファイルに以下の Gradle プロパティを設定してください:

kotlin.internal.diagnostics.ignoreWarningMode=true
Experimental

新しい実験的なビルドツール API (BTA)

Kotlin は、Gradle、Maven、Amper などのさまざまなビルドシステムで使用できます。しかし、インクリメンタルコンパイルのサポートや Kotlin コンパイラプラグイン、デーモン、Kotlin Multiplatform との互換性など、フル機能セットをサポートするために各システムに Kotlin を統合するには、多大な労力が必要です。

このプロセスを簡素化するため、Kotlin 2.2.0 では新しい実験的なビルドツール API (BTA) が導入されました。BTA は、ビルドシステムと Kotlin コンパイラエコシステムの間の抽象化レイヤーとして機能するユニバーサルな API です。このアプローチにより、各ビルドシステムは単一の BTA エントリポイントをサポートするだけで済みます。

現在、BTA は Kotlin/JVM のみをサポートしています。JetBrains の Kotlin チームはすでに Kotlin Gradle プラグイン (KGP) と kotlin-maven-plugin でこれを使用しています。これらのプラグインを通じて BTA を試すことができますが、API 自体は独自のビルドツール統合での一般的な使用にはまだ準備ができていません。BTA プロポーザルに興味がある場合やフィードバックを共有したい場合は、この KEEP プロポーザルを参照してください。

BTA を試すには:

  • KGP の場合、gradle.properties ファイルに以下のプロパティを追加します:
kotlin
kotlin.compiler.runViaBuildToolsApi=true
  • Maven の場合、何もする必要はありません。デフォルトで有効になっています。

現在、BTA は Maven プラグインに直接的なメリットをもたらしませんが、Kotlin デーモンのサポートインクリメンタルコンパイルの安定化 など、新しい機能をより迅速に提供するための強固な基盤を築きます。

KGP の場合、BTA を使用することで次のようなメリットがすでにあります:

改善された「プロセス内」コンパイラ実行戦略

KGP は 3 つの Kotlin コンパイラ実行戦略 をサポートしています。コンパイラを Gradle デーモンプロセス内で実行する「プロセス内(in process)」戦略は、以前はインクリメンタルコンパイルをサポートしていませんでした。

今回、BTA を使用することで、「プロセス内」戦略がインクリメンタルコンパイルを サポート するようになりました。これを使用するには、gradle.properties ファイルに以下のプロパティを追加してください:

kotlin
kotlin.compiler.execution.strategy=in-process

Kotlin から異なるコンパイラバージョンを構成できる柔軟性

ビルドスクリプトの非推奨事項に対応しつつ、新しい言語機能を試すために、KGP は古いバージョンのまま、コード内でより新しい Kotlin コンパイラバージョンを使用したい場合があります。あるいは、KGP のバージョンを更新しても、古い Kotlin コンパイラバージョンを維持したい場合もあります。

BTA により、これが可能になります。build.gradle.kts ファイルでの構成方法は以下の通りです:

kotlin
// build.gradle.kts
import org.jetbrains.kotlin.buildtools.api.ExperimentalBuildToolsApi
import org.jetbrains.kotlin.gradle.ExperimentalKotlinGradlePluginApi

plugins { 
    kotlin("jvm") version "2.2.0"
}

group = "org.jetbrains.example"
version = "1.0-SNAPSHOT"

repositories { 
    mavenCentral()
}

kotlin { 
    jvmToolchain(8)
    @OptIn(ExperimentalBuildToolsApi::class, ExperimentalKotlinGradlePluginApi::class) 
    compilerVersion.set("2.1.21") // 2.2.0 とは異なるバージョン
}

BTA は、KGP と Kotlin コンパイラバージョンの構成において、過去 3 つのメジャーバージョンと 1 つの将来のメジャーバージョンをサポートしています。したがって、KGP 2.2.0 では、Kotlin コンパイラバージョン 2.1.x、2.0.x、および 1.9.25 がサポートされます。KGP 2.2.0 は、将来の Kotlin コンパイラバージョン 2.2.x および 2.3.x とも互換性があります。

ただし、異なるコンパイラバージョンをコンパイラプラグインと一緒に使用すると、Kotlin コンパイラ例外が発生する可能性があることに注意してください。Kotlin チームは、将来のリリースでこれらの問題に対処する予定です。

これらのプラグインで BTA を試してみて、KGP および Maven プラグイン の専用 YouTrack チケットでフィードバックをお送りください。

標準ライブラリ

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

Stable になった Base64 エンコーディングとデコーディング

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

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

    Base64.DefaultBase64 クラスのコンパニオンオブジェクトです。 その結果、Base64.Default.encode() および Base64.Default.decode() の代わりに Base64.encode() および Base64.decode() として関数を呼び出すことができます。

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

  • Base64.Mime は、MIME エンコーディングスキームを使用し、エンコーディング中に 76 文字ごとに改行セパレータを挿入し、デコーディング中に不正な文字をスキップします。

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

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

以下に例を示します:

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

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

Base64.Default.decode("Zm8=") // foBytes
// あるいは:
// Base64.decode("Zm8=")

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

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

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 APIStable(安定版) になりました。 数値と 16 進文字列の間の変換に使用できます。

例:

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

詳細は 16 進数のフォーマットと解析のための新しい HexFormat クラス を参照してください。

Compose コンパイラ

本リリースでは、Compose コンパイラに composable 関数参照のサポートが導入され、いくつかの機能フラグのデフォルトが変更されました。

@Composable 関数参照のサポート

Compose コンパイラは、Kotlin 2.2.0 リリースから composable 関数参照の宣言と使用をサポートします:

kotlin
val content: @Composable (String) -> Unit = ::Text

@Composable fun App() {
    content("My App")
}

composable 関数参照は、実行時に composable ラムダオブジェクトとはわずかに異なる動作をします。特に、composable ラムダは ComposableLambda クラスを拡張することで、スキップ(skipping)のより細かな制御を可能にします。関数参照は KCallable インターフェースを実装することが期待されるため、同じ最適化をそれらに適用することはできません。

PausableComposition 機能フラグがデフォルトで有効に

Kotlin 2.2.0 から、PausableComposition 機能フラグがデフォルトで有効になりました。このフラグは、再起動可能な関数に対する Compose コンパイラの出力を調整し、ランタイムが強制的にスキップ動作を行えるようにします。これにより、各関数をスキップすることで実質的にコンポジションを一時停止できるようになります。これにより、重いコンポジションをフレーム間に分割することが可能になり、将来のリリースでのプリフェッチ(prefetching)に使用される予定です。

この機能フラグを無効にするには、Gradle 設定に以下を追加してください:

kotlin
// build.gradle.kts
composeCompiler {
    featureFlag = setOf(ComposeFeatureFlag.PausableComposition.disabled())
}

OptimizeNonSkippingGroups 機能フラグがデフォルトで有効に

Kotlin 2.2.0 から、OptimizeNonSkippingGroups 機能フラグがデフォルトで有効になりました。この最適化により、スキップしない composable 関数に対して生成されるグループ呼び出しが削除され、ランタイムパフォーマンスが向上します。 実行時の動作に目に見える変化はないはずです。

問題が発生した場合は、機能フラグを無効にすることで、この変更が原因かどうかを確認できます。 問題は Jetpack Compose 問題トラッカー に報告してください。

OptimizeNonSkippingGroups フラグを無効にするには、Gradle 設定に以下を追加してください:

kotlin
composeCompiler {
    featureFlag = setOf(ComposeFeatureFlag.OptimizeNonSkippingGroups.disabled())
}

非推奨となった機能フラグ

StrongSkipping および IntrinsicRemember 機能フラグは非推奨となり、将来のリリースで削除される予定です。 これらの機能フラグを無効にする必要があるような問題が発生した場合は、Jetpack Compose 問題トラッカー に報告してください。

破壊的変更と非推奨事項

このセクションでは、注目すべき重要な破壊的変更と非推奨事項について説明します。本リリースにおけるすべての破壊的変更と非推奨事項の完全な概要については、互換性ガイド を参照してください。

  • Kotlin 2.2.0 以降、コンパイラは -language-version=1.6 または -language-version=1.7 をサポートしなくなりました。 1.8 より古い言語機能セットはサポートされませんが、言語自体は Kotlin 1.0 との完全な後方互換性を維持しています。

  • Ant ビルドシステムのサポートが非推奨となりました。Ant 向けの Kotlin サポートは長い間活発に開発されておらず、ユーザーベースが比較的少ないため、今後メンテナンスする予定はありません。 Ant サポートは 2.3.0 で削除する予定です。

  • Kotlin 2.2.0 では、Gradle における kotlinOptions{} ブロックの非推奨レベルがエラーに引き上げられました。 代わりに compilerOptions{} ブロックを使用してください。ビルドスクリプトの更新に関するガイダンスについては、kotlinOptions{} から compilerOptions{} への移行 を参照してください。

  • Kotlin スクリプティングは依然として Kotlin エコシステムの重要な部分ですが、より良い体験を提供するために、カスタムスクリプティングや gradle.kts および main.kts スクリプトなどの特定のユースケースに焦点を当てています。 詳細については、更新された ブログ投稿 を参照してください。その結果、Kotlin 2.2.0 では以下のサポートが非推奨となります:

    • REPL: kotlinc 経由で REPL を引き続き使用するには、-Xrepl コンパイラオプションでオプトインしてください。
    • JSR-223: この JSRWithdrawn(取り下げ) 状態にあるため、JSR-223 実装は言語バージョン 1.9 では引き続き動作しますが、将来的に K2 コンパイラを使用するように移行されることはありません。
    • KotlinScriptMojo Maven プラグイン: このプラグインは十分な関心が得られませんでした。使用し続けるとコンパイラ警告が表示されます。
  • Kotlin 2.2.0 では、KotlinCompileTool 内の setSource() 関数が、構成されたソースに追加するのではなく、それらを置き換える ようになりました。 既存のソースを置き換えずに追加したい場合は、source() 関数を使用してください。

  • BaseKapt における annotationProcessorOptionProviders の型が、MutableList<Any> から MutableList<CommandLineArgumentProvider> に変更されました。コードで現在リストを単一要素として追加している場合は、add() 関数の代わりに addAll() 関数を使用してください。

  • レガシーな Kotlin/JS バックエンドで使用されていたデッドコード削除 (DCE) ツールの非推奨化に伴い、DCE に関連する残りの DSL が Kotlin Gradle プラグインから削除されました:

    • org.jetbrains.kotlin.gradle.dsl.KotlinJsDce インターフェース
    • org.jetbrains.kotlin.gradle.targets.js.dsl.KotlinJsBrowserDsl.dceTask(body: Action<KotlinJsDce>) 関数
    • org.jetbrains.kotlin.gradle.dsl.KotlinJsDceCompilerToolOptions インターフェース
    • org.jetbrains.kotlin.gradle.dsl.KotlinJsDceOptions インターフェース

    現在の JS IR コンパイラ は標準で DCE をサポートしており、@JsExport アノテーションにより、DCE 中にどの Kotlin 関数やクラスを保持するかを指定できます。

  • 非推奨となっていた kotlin-android-extensions プラグインは Kotlin 2.2.0 で削除されましたParcelable 実装ジェネレータには kotlin-parcelize プラグインを、シンセティックビューには Android Jetpack の ビューバインディング を代わりに使用してください。

  • 実験的な kotlinArtifacts API は Kotlin 2.2.0 で非推奨となりました最終的なネイティブバイナリをビルド するには、Kotlin Gradle プラグインで利用可能な現在の DSL を使用してください。移行に不十分な場合は、この YouTrack 課題 にコメントを残してください。

  • Kotlin 1.9.0 で非推奨となった KotlinCompilation.source は、Kotlin Gradle プラグインから削除されました

  • 実験的なコモナイゼーション(commonization)モードのパラメータは、Kotlin 2.2.0 で非推奨となりました。 無効なコンパイル成果物を削除するには、コモナイゼーションキャッシュをクリアしてください。

  • 非推奨となっていた konanVersion プロパティは、CInteropProcess タスクから削除されました。 代わりに CInteropProcess.kotlinNativeVersion を使用してください。

  • 非推奨の destinationDir プロパティを使用すると エラーになるようになりました。 代わりに CInteropProcess.destinationDirectory.set() を使用してください。

ドキュメントの更新

本リリースでは、Kotlin Multiplatform ドキュメントの KMP ポータル への移行など、注目すべきドキュメントの変更が行われました。

さらに、新しいページやチュートリアルを作成し、既存のものを刷新しました。

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

新規および刷新されたページ

  • AI 向け Kotlin の概要 – AI 搭載アプリケーションを構築するための Kotlin の機能を紹介します。
  • Dokka 移行ガイド – Dokka Gradle プラグインの v2 への移行方法を学びます。
  • – JVM 向けにコンパイルされた Kotlin クラスのメタデータの読み取り、変更、および生成に関するガイダンスを提供します。
  • CocoaPods 統合 – チュートリアルやサンプルプロジェクトを通じて、環境のセットアップ、Pod 依存関係の追加、または Kotlin プロジェクトを CocoaPod 依存関係として使用する方法を学びます。
  • iOS 安定版リリースをサポートするための Compose Multiplatform の新ページ:
  • Compose ホットリロード – デスクトップターゲットで Compose ホットリロードを使用する方法と、既存のプロジェクトに追加する方法を学びます。
  • Exposed 移行 – データベーススキーマの変更を管理するために Exposed が提供するツールについて学びます。

Kotlin 2.2.0 へのアップデート方法

Kotlin プラグインは、IntelliJ IDEA および Android Studio にバンドルされたプラグインとして提供されています。

新しい Kotlin バージョンにアップデートするには、ビルドスクリプト内の Kotlin バージョンを 2.2.0 に変更してください。