Kotlin Academy · レッスン

制限事項

値クラスでできないことを学びます

レッスン 4/413 ステップ

「制限事項」は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フィードバックを取得できます。ローカル設定は不要です。

このコースのすべてのレッスン

  1. 型エイリアス
  2. インライン値クラス
  3. ユースケース
  4. 制限事項
← Kotlin Academyに戻る