javaプログラマーは何度もNullPointerExceptionと対面し、そのたびにコードとにらめっこをしてきたことだと思います。 そもそもjavaは参照型を扱う言語であり、null値の参照型変数を参照してしまうと上記の例外を発生させてしまいます。 その例外を根本的に発生させないため、kotlinには予期せぬnullを入れないための概念があります。 それがnull安全という仕組みです。
null 安全kotlinはデフォルトでnullを許容していません。 そのため、nullを想定するかしないかを(コメントアウトではなく言語レベルで)はっきりと明示させる必要があります。 遅れましたが、つまり null安全とは「ある参照型がnullを許容するかnullを許容しないかを明確に区別させる」仕組みです。 まず、ダメな例をあげてみます。
var s: String = null
var s: String = "hello"
s = null
この 2 例はどちらもnullを代入しようとした段階でコンパイルエラーが発生してしまいます。 さきほども説明しましたが、kotlinはデフォルトでnullを許容していません。(大事なことなので) この場合の「s」は非 Null型 (Non-Null Type) として扱います。 つまりは、「変数sはnull を許容しないString型」として扱われることになります。
では、どうすればい良いのか。 解決方法はとても簡単で、型名の後ろに「?」を付けるだけです。 この方法を用いた良い例をあげます。
var s: String? = null
var s: String? = "hello"
s = null
見てわかるように型名の後ろに「?」を付けただけです。 これだけで「s」はNull許容型 (Nullable Type) として扱います。 ただ、「?」を付けただけですが、「String」と「String?」は別の型として考えます。
ここで気づいた人もいると思いますが、kotlinという言語は明示するまで「nullが存在しない」ということです。
さて、「String」と「String?」は別と言いましたが、Null許容型で宣言した変数の参照も変わります。 方法は同じように変数名の後ろに「?」を付けるだけです。 非Null型、Null許容型の2例を示します。
var s: String = "hello"
println(s.length) // OK
println(s?.length) // コンパイルエラー
var s: String? = "hello"
println(s?.length) // OK
println(s.length) // コンパイルエラー
非Null型変数にNull許容型変数の代入はできませんが、Null許容型変数に非Null型変数の代入は可能です。
var a: String = "hello"
var b: String? = a // OK
var a: String? = "hello"
var b: String = a // コンパイルエラー
先程、非Null型変数にNull許容型変数の代入はできませんと言いましたが、代入を可能にする方法が存在します。 もっと簡単に言うと、Null許容型変数を非Null型として扱うことが可能です。 方法はこれも簡単で、変数名の後ろに「!!」を付けるだけです。
var a: String? = "hello"
var b: Srting = a!! // OK
この例では「b」は非Null型のString型となります。 元々nullを許容してない言語であるkotlinでnullを扱う場合はNull許容型を参照したり、非Null型に代入したりする際にnullチェックを行うことで、nullを明示することが可能です。 今回は条件式 (if文) を用いたnullチェック例を示します。
var s: String? ="hello"
if (s != null) {
println(s.length) // OK
}
println(s?.length) // OK
println(s.length) // コンパイルエラー
このnullチェックではif文のブロック内のみnullを許容していないので、外側での参照は通常通り「?」を付ける必要があります。
以上でnullに関するお話はこの記事では終わりです。
型キャストnullチェックのif文に近い機能があります。 任意のブロックを任意の型でキャストする事が可能です。 まずは、ブロック内のみ型キャストする例を示します。
fun sampleFun(obj: Any): Int? {
if (obj is String) {
return obj.length // objはString型
}
return null // objはAny型
}
次は、ブロック外を型キャストする例を示します。
fun sampleFun(obj: Any): Int? {
if (obj !is String)
return null // objはAny型
return obj.length // objはString型
}
最後に、一部ブロック内かつ条件式内で型キャストを行う例を示します。
fun getStringLength(obj: Any): Int? {
if (obj is String && obj.length > 0)
return obj.length // objはString型
return null // objはAny型
}
最後の例では条件式内でもキャストが反映されていることが分かると思いますが、とても面白い機能ですよね。
まとめkotlinはデフォルトでnullが許容されおらず、nullが存在しないことを前提とした言語です。 nullを許容したい場合はnull安全という仕組みに基づいて宣言、操作する方法について説明しました。 また、nullチェックに似た型キャストという仕組みについても説明しました。
この記事を読んで少しでもkotlinに興味を持っていただけたら幸いです。
- 閲覧数 2735
コメントを追加