制限事項
値クラスでできないことを学びます
「制限事項」はCoddyKit上の無料Kotlin Academyレッスンです。 これはレッスン4/4です。 下記で完全なレッスンを無料で読むことができます。その後、ブラウザ内の組み込みコードエディタと24時間対応のAIチューターでハンズオン演習できます。 これはKotlin Academy学習パスの一部であり、ウェブとCoddyKitアプリ全体で進捗が同期されます。 Kotlin Academyコースには全4レッスンが含まれています。
制限を知る
値クラスは強力ですが、制約もあります。その制限を理解しておくと、適切なツールを選び、予期しない問題を避けられます。
プロパティは1つだけ
値クラスは1つの値をラップします。複数のフィールドをまとめるには、通常のクラスまたはdata classが必要です。
// @JvmInline value class Range(val lo: Int, val hi: Int) // not allowed
data class Range(val lo: Int, val hi: Int)
fun main() {
println(Range(1, 10))
}値以外の初期化状態は持てない
値クラスには、コンストラクタプロパティ以外のバッキングフィールドを定義できません。バッキングフィールドを持つ追加のvar状態は許可されません。
@JvmInline
value class Counter(val value: Int) {
// val cached: Int = value * 2 // not allowed: extra backing field
val doubled: Int get() = value * 2 // computed is fine
}
fun main() {
println(Counter(3).doubled)
}継承できない
値クラスには暗黙的にfinalが付いています。他のクラスを継承することも、値クラスを継承させることもできません。実装できるのはインターフェースだけです。
interface Named { val label: String }
@JvmInline
value class Tag(val text: String) : Named {
override val label: String get() = text
}
fun main() {
println(Tag("urgent").label)
}ボックス化でコストが戻る
値をnullable型、ジェネリック型、またはインターフェース型として使うと、オーバーヘッドゼロという利点は失われます。その場合、コンパイラーは値を実際のオブジェクトにボックス化します。
@JvmInline
value class Id(val raw: Int)
fun main() {
val list: List<Id> = listOf(Id(1), Id(2)) // boxed inside the list
println(list.map { it.raw })
}オブジェクトIDを持たない
値クラスには安定した参照アイデンティティがありません。===による参照の等価性には意味がなく、オブジェクトのアイデンティティが重要な場所(同期ロックなど)では使用できません。
@JvmInline
value class Code(val value: Int)
fun main() {
val a = Code(5)
val b = Code(5)
println(a == b) // structural equality works
}lateinitにも委譲プロパティにもできない
基になる値にlateinitを適用することはできません。また、値クラスは単一フィールドでのプロパティ委譲をサポートしていません。値はコンストラクターで設定する必要があります。
@JvmInline
value class Slug(val value: String)
fun main() {
val s = Slug("hello-world") // must be provided up front
println(s.value)
}JVMの名前マングリング
JVMでは、値クラスのパラメーターを受け取る関数のバイトコード上の名前が、衝突を避けるためにマングリングされます。そのためJavaとの相互運用が複雑になり、Java側からはきれいに見えない場合があります。
@JvmInline
value class Hz(val value: Int)
fun tune(freq: Hz) = freq.value
fun main() {
println(tune(Hz(440))) // simple from Kotlin; mangled from Java
}複数フィールドのラッパーには不向き
プロパティを2つ持たせたいと思ったなら、値クラスは適切なツールではありません。より豊かな構造を得る代わりに割り当てを受け入れ、data classを使いましょう。
data class Coordinate(val lat: Double, val lng: Double)
fun main() {
println(Coordinate(41.0, 29.0))
}制限のまとめ
値クラスには次のことができません。
- プロパティを2つ以上持つ
- 追加のバッキングフィールドや
lateinitを持つ - クラスを継承する、またはクラスに継承させる
- 参照アイデンティティを提供する
- 常にボックス化を避ける
適切に使い分ける
単一の、検証済みで型安全な値には値クラスを使います。データをまとめるにはdata classを使います。安全性を必要とせず、可読性だけを高めたい場合は型エイリアスを使います。それぞれに適した用途があります。
理解度チェック
値クラスの制限についての理解度を確認しましょう。
まとめ
値クラスの制限について、次のことを学びました。
- プロパティは1つだけで、追加のバッキングフィールドは持てない
- 継承できず、アイデンティティも持たない
- nullable、ジェネリック、インターフェースとして使うとボックス化される
- JVMの名前マングリングにより、Javaとの相互運用が複雑になる
必要に応じてツールを使い分けましょう。
AI チューターと学ぶ Kotlin — 無料
ブラウザでリアルコードを書いて実行し、24/7 の AI チューターから瞬時にサポートを受け、ウェブまたはアプリで続きから学習できます。
- コース
- 51
- レッスン
- 203
よくある質問
「制限事項」レッスンは無料ですか?
はい。「制限事項」の完全なテキストはこのウェブで無料で読めます。インタラクティブに演習し(組み込みコードエディタと24時間対応のAIチューター)、Kotlin Academyコースの残りをアンロックするには、CoddyKit PROにアップグレードしてください。 Kotlin Academyコースには全4レッスンが含まれています。
「制限事項」で何を学びますか?
値クラスでできないことを学びます ブラウザで直接実行するハンズオンコードでKotlin Academyを演習し、24時間対応のAIチューターがレッスンを進める中での質問に答えます。
Kotlin Academyを始めるのに経験は必要ですか?
事前経験は必要ありません。CoddyKitのKotlin Academyは初級者から上級者向けに構成されているため、ここから始めるか最初から始めて、自分のペースで進むことができます。 これはレッスン4/4です。
「制限事項」レッスンにはどのくらい時間がかかりますか?
ほとんどのCoddyKitレッスンは約5~10分かかります。各レッスンはコンパクトでインタラクティブなので、着実に進歩し、ウェブとアプリ全体で正確に前回の場所から再開できます。
このKotlin Academyレッスンでコードを書いて実行できますか?
はい。すべてのKotlin Academyレッスンに組み込みコードエディタが含まれているため、ブラウザでリアルコードを書いて実行し、即座のAIフィードバックを取得できます。ローカル設定は不要です。