dogwood008.github.io KotlinのリファレンスのNull安全のページが英語しかなさそうだったので、ざっくり翻訳しつつ例を足したりした。
Null安全
Kotlinでは下記の要因以外でNPEを起こすことが無いよう作られている。
- 明示的な
throw NullPointerException()
!!
演算子を使用した場合- 外部のJavaコードが原因の場合
- コンストラクタで利用可能な初期化されていない
this
が使用されている
Null可能値
Null値を取りうる変数は明示的にNull可能値としなければならない
var a: String = "abc" a = null // コンパイルエラー val l = a.length var b: String? = "abc" b = null // ok val l = b.length // bはNullableなのでエラー
Non-Nullableなオブジェクトは安全にプロパティにアクセスできる。
NullableなオブジェクトはNPEの可能性があるためエラーとなる。
Nullableなオブジェクトにアクセスしたい場合
Nullチェックを行う
val a :String? = "testa" var b :String? = "testb" var c :String? = "testc" val l = if (a != null) print("String of length ${a.length}\n") else print("\n") if (b != null && b.length > 0) print("String of length ${b.length}\n") else print("Empty string\n") if (c != null && c.length > 0){ c = null // nullを代入できてしまう! print("String of length ${c.length}\n") }else{ print("Empty string\n") }
Nullチェックを行った後は、Nullableなオブジェクトが自動でキャストされ、
プロパティにアクセスが可能になる。
※var
の場合、チェック後にnullを代入出来てしまうため注意
安全呼び出し
val l:Int? = b?.length
上記の場合、bがnullならnullを、そうでなければb.length
をl
に代入する。
Intまたはnullが返却されるため型はInt?となる
bob?.department?.head?.name
安全呼び出しはチェーンすることができ、上記の場合はいずれかのプロパティがnullならnullを返す。
その他のNullに関する演算子等
エルビス演算子
val l: Int = b?.length ?: -1
上記の場合,b?.length
がnullでない場合はb.length
、nullの場合は右辺が評価されて-1を返す。
!!演算子
val l = b!!.length()
上記の場合、b.length()
がnullであればNPEを発生させる。
nullでない場合はエルビス演算子と同様にb.length
の値を返す。
セーフキャスト
val aInt: Int? = a as? Int
上記の例ではa
がnullの場合はaInt
はnull、nullでない場合はa
となる。
KotlinのキャストはNull安全でないため、正しい型でないとClassCastException
が発生してしまう。
セーフキャストを行う事でエラーを避けて安全なキャストができる。