Kotlinでは、原始型や小さな構造体のラッパーを扱う際のランタイムオーバーヘッドを最小化するために、インライン/値クラス(現在は値クラスと呼ばれています)の概念が導入されました。このアイデアは、他の言語(例えば、C#の構造体)から借用されており、型安全性を損なうことなくパフォーマンスを向上させるために有用です。
最適化なしでラッパークラス(例えば、エンティティタイプや識別子のためのラッパー)を作成すると、追加のオブジェクトがメモリに生成され、パフォーマンスやGCに影響を及ぼし、ボクシング/アンボクシングのオーバーヘッドが発生する可能性があります。しばしば、厳密な型付け(例えば、Intの代わりにUserId)が必要だと考えますが、実際にオブジェクトを作成したくありません。
値クラスは値修飾子を使用して宣言されます。ほとんどの状況では、JVMは追加のオブジェクトを作成せず、値クラスはそのフィールドに直接置換されます(インライン化)。これにより型安全性が提供され、パフォーマンスは「ただのInt」に近いものになります。
コード例:
@JvmInline value class UserId(val value: Int) fun showId(id: UserId) = println(id.value) val id = UserId(15) showId(id) // 別のUserIdオブジェクトを作成せず
主な特徴:
値クラスは複数のプロパティを持つことができますか?
いいえ、値クラスは1つのプロパティしか含むことができません。
// エラー: // value class Money(val amount: Int, val currency: String)
nullableプロパティを持つ値クラスを作成できますか?
値クラスのvalueフィールドはnullableにすることはできません — 非nullableタイプのみです。
// エラー: // value class Name(val value: String?)
値クラスで継承を使用できますか?
値クラスは継承をサポートせず、抽象またはsealedにはできません。
// エラー: // value class NewId(val value: Int): BaseId()
開発者が2つのプロパティを持つエンティティ用に値クラスを作成し、コンパイルエラーを受けました。
長所:
開発者が1つのフィールド(例えば、UserId)の識別子タイプに値クラスを使用し、迅速かつ安全に動作させています。
長所: