web-dev-qa-db-ja.com

Kotlinがプリミティブ型でlateinitを使用できないのはなぜですか?

Kotlin言語では、デフォルトで、各変数が導入されたときに初期化する必要があります。これを回避するには、lateinitキーワードを使用できます。初期化される前にlateinit変数を参照すると、実行時例外が発生します。

ただし、lateinitはプリミティブ型では使用できません。なぜそうですか?

35
Kallja

オブジェクトタイプの場合、Kotlinはnull値を使用して、lateinitプロパティが初期化されていないことを示し、プロパティにアクセスしたときに適切な例外をスローします。

プリミティブ型の場合、そのような値はないため、プロパティを初期化されていないものとしてマークし、lateinitが提供する必要のある診断を提供する方法はありません。 (何らかの種類の別のマーカーを使用することもできますが、リフレクションによってフィールドを初期化するときにそのマーカーは更新されません。これはlateinitの主な使用例です)。

したがって、lateinitはオブジェクトタイプのプロパティでのみサポートされます。

34
yole

簡単な答えは、プリミティブでは常に0がデフォルトで、null許容型nullがデフォルトです。型安全システムを回避するには、null不可の非プリミティブ型のみがlateinitを必要とする場合があります。

実際には、値がbefore最初のアクセスであり、staticallyであることが証明されている限り、Kotlinで変数を初期化する必要はありません。つまり、このコードは完全に有効です。

fun main(args: Array<String>) {
    var x: Int
    val y: Double

    x = 0
    y = x + 0.1

    println("$x, $y") 
}

ただし、初期化を静的に証明できない(まれな)場合があります。最も一般的なケースは、任意の形式の依存性注入を使用するクラスフィールドです。

class Window {
    @Inject lateinit parent: Parent
}
2
voddan