Kotlinのnullableな型とnon-nullな型

Kotlinでは、nullとなり得る変数とnullとなり得ない変数を区別して扱います。これにより、変数がnullになり得るか、なり得ないかを型のレベルで区別して取り扱うことが可能です。ここでは、nullとなり得る変数をnullableな変数、nullになり得ない変数をnon-nullな変数と呼びます。

nullableな変数の宣言

nullableな変数を宣言するためには、型の名称の後ろに?を付けて宣言します。以下のコードでは、nullableなString型の変数nullableStringを宣言しています。

var nullableString: String? = "string"

nullableStringには、String型の値の他に、nullを代入することが可能です。

nullableString = null

non-nullな変数の宣言

これに対して、non-nullな変数を宣言する場合は、型の名称の後ろに?を付けずに変数を宣言します。

var nonNullString: String = "string"

また、non-nullな変数を宣言する場合には、型推論を用いることも可能です。

var nonNullString = "string"

non-nullな変数にnullを代入することはできません。例えば、以下のコードはコンパイルエラーとなります。

nonNullString = null // コンパイルエラー

Kotlinでは、non-nullな変数にnullを代入することは許されていません。これにより、変数がnullになり得るか、なり得ないかを型のレベルで識別することが可能です。

nullableな型とnon-nullな型の関係

Kotlinでは、全てのnullableな型はAny?型を親クラスに持ちます。例えば、String?型はAny?型を親クラスに持ちます。

println(nullableString is Any?) // true

一方、Kotlinの全てのnon-nullな型は、Any型を親クラスに持ちます。例えば、String型はAny型を親クラスに持ちます。

println(nonNullString is Any) // true

さらに、Any型はAny?型を親クラスに持ちます。すなわち、Any?型の変数にAny型の値を代入することは可能ですが、逆にAny型の変数にAny?型の値を代入することはできません。

これは同時に、nullableな変数にnon-nullな値を代入することは可能ですが、non-nullな値にnullableな値を代入することはできない、ということを意味します。

このようにして、Kotlinではnullableな型とnon-nullな型を区別して取り扱い、null安全を実現しています。

筆者

茨城県つくば市在住のソフトウェアエンジニアです。得意領域はAndroidとFlutterです。「Jetpack ComposeによるAndroid MVVMアーキテクチャ入門」の著者です。

👉もっと詳しく