はじめに
Kotlin の value class は、旧来の inline class の進化版・正式版です。Kotlin 1.5 から正式リリースされ、inline class は非推奨になりました。
1. 定義方法
@JvmInline
value class UserId(val id: Int)
@JvmInline
value class Email(val value: String)
-
@JvmInlineアノテーションは JVM との相互運用のために必須 - 中身は 単一プロパティのみ(複数は不可)
2. 仕組み
- 通常のクラスのように型安全性を提供
- 実行時には ラップされずに中身の値にインライン化 される(パフォーマンス◎)
-
UserIdはIntとして扱われるが、型レベルでIntと区別可能
3. 使用例
@JvmInline
value class UserId(val id: Int)
fun greet(userId: UserId) {
println("Hello, user #${userId.id}")
}
fun main() {
val userId = UserId(42)
greet(userId) // Hello, user #42
}
実行時には UserId のオブジェクト生成はなく、ただの Int として扱われる。
4. 制約
- フィールドは 1つだけ
-
継承できない(
open/abstract/sealedは不可) - init ブロックなし(バリデーションはファクトリメソッドで実装する)
-
nullable の場合はボックス化される
→UserId?はオブジェクトとして扱われる可能性あり。
5. よくある用途
-
型安全な ID
value class CustomerId(val value: Int) value class OrderId(val value: Int)→
Intの混同を防ぐ。 -
単位付きの値
value class Meter(val value: Double) value class Second(val value: Double)→
MeterとSecondを区別して計算できる。 -
ラッパーで意味を明確化
value class Email(val value: String) value class PhoneNumber(val value: String)
6. inline class との違い
| 項目 | inline class (旧) | value class (新) |
|---|---|---|
| Kotlin バージョン | 1.3〜1.4 | 1.5〜正式版 |
| 定義方法 | inline class |
value class |
| JVM 互換性 | 不安定 |
@JvmInline で安定 |
| 推奨度 | 非推奨 | ✅ 正式に使用可能 |
まとめ
Kotlin 1.5+ では value class を使うのが正解です。
inline class は古いコードのために残ってるだけと思ってOKです。