Skip to content

KotlinでのJavaレコードの使用

_レコード_はJavaにおいて、不変データを格納するためのクラスです。レコードは、固定された一連の値(レコードコンポーネント)を持ちます。 これらはJavaにおいて簡潔な構文を持ち、ボイラープレートコードを書く手間を省きます。

java
// Java
public record Person (String name, int age) {}

コンパイラは、java.lang.Recordを継承したfinalクラスを、以下のメンバーとともに自動的に生成します。

  • 各レコードコンポーネントに対応するprivate finalフィールド
  • すべてのフィールドに対応するパラメータを持つpublicコンストラクタ
  • 構造的等価性を実装するための一連のメソッド:equals()hashCode()toString()
  • 各レコードコンポーネントを読み取るためのpublicメソッド

レコードはKotlinのデータクラスと非常によく似ています。

KotlinコードからのJavaレコードの使用

Javaで宣言されたコンポーネントを持つレコードクラスは、Kotlinでプロパティを持つクラスと同じように使用できます。 レコードコンポーネントにアクセスするには、Kotlinプロパティと同じようにその名前を使用するだけです。

kotlin
val newPerson = Person("Kotlin", 10)
val firstName = newPerson.name

Kotlinでのレコード宣言

Kotlinはデータクラスに対してのみレコード宣言をサポートしており、そのデータクラスは要件を満たす必要があります。

Kotlinでレコードクラスを宣言するには、@JvmRecordアノテーションを使用します。

NOTE

既存のクラスに@JvmRecordを適用することは、バイナリ互換の変更ではありません。クラスプロパティアクセサの名前付け規則が変更されます。

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

このJVM固有のアノテーションにより、以下の生成が可能になります。

  • クラスファイル内のクラスプロパティに対応するレコードコンポーネント
  • Javaのレコード名前付け規則に従って命名されたプロパティアクセサメソッド

データクラスは、equals()hashCode()、およびtoString()メソッドの実装を提供します。

要件

@JvmRecordアノテーションを付けてデータクラスを宣言するには、以下の要件を満たす必要があります。

  • クラスは、JVM 16バイトコードをターゲットとするモジュール内にある必要があります(-Xjvm-enable-previewコンパイラオプションが有効な場合は15でも可)。
  • すべてのJVMレコードは暗黙的にjava.lang.Recordを継承するため、このクラスは明示的に他のクラス(Anyを含む)を継承できません。ただし、インターフェースを実装することはできます。
  • このクラスは、対応するプライマリコンストラクタパラメータから初期化されるものを除き、バッキングフィールドを持つプロパティを宣言できません。
  • このクラスは、バッキングフィールドを持つ可変プロパティを宣言できません。
  • このクラスはローカルクラスであってはなりません。
  • クラスのプライマリコンストラクタは、クラス自体と同じ可視性を持つ必要があります。

JVMレコードの有効化

JVMレコードには、生成されるJVMバイトコードのターゲットバージョン16以上が必要です。

明示的に指定するには、GradleまたはMavenjvmTargetコンパイラオプションを使用します。

さらなる議論

さらなる技術的な詳細や議論については、このJVMレコードの言語提案を参照してください。