KotlinとNull Safetymmj blog


最近Kotlinでサーバサイドのプログラムを書いています。
KotlinはJavaをベースに改良された言語ですが、一番の特徴は変数がデフォルトでNull非許容型となっていることでしょう。これによりプログラム内部でNullPointerExceptionが発生することがめったに起こらなくなります。(実際にはJavaのライブラリとの兼合いで発生するケースはあります)

KotlinにはNull非許容型を扱うためJavaにはない構文がいくつか追加されており、最初にコードを読むといささか戸惑うかと思います。
よく使う構文をまとめてみました。

通常の変数

変数は初期化した値から自動で型が決定します。
明示的に型を指定することもでき、その場合はセミコロンのあとに型を記述します。(TypeScriptと同様の構文です)
このようにリテラルを指定した場合、もしくは型を指定した場合は変数はNull非許容型となり、nullを代入しようとするとコンパイルエラーになります。

var test1 = "aaa"
//var test1: String = "aaa" //↑と同じ
test1 = "bbb" // OK
//test1 = null // Compile Error

null許容型

nullを代入できるようにするには型の後ろに”?”を記述します。

var test2: String? = "ccc"
test2 = "ddd" // OK
test2 = null // OK

安全な呼び出し

変数がnullの場合にメソッドを呼び出すとNullPointerExceptionに…なんてことがないように、null許容型の変数からメソッドを呼び出すとコンパイルエラーになります。Kotlinは賢いので。
コンパイルエラーにならないようにするには”.”ではなく”?.”を使用します。この場合、変数がnullの場合はメソッドの呼び出しをスキップします。面白いことに代入時の左辺にもこの演算子が使用できます。

var test3: String? = null
//var test3b = test3.toUpperCase() // Compile Error
var test3b = test3?.toUpperCase() // OK
test3?.toUpperCase()?.toLowerCase()?.length // 複数回呼び出しもOK

class Test3 {
  var name: String? = null
}

var test3c: Test3? = null
test3c?.name = test3?.toUpperCase() // 代入もOK(?!)

強制キャスト

nullでないことがわかっている場合に、null許容型からnull非許容型に強制的に変換すればコードが見やすくなります。
この場合は変数のあとに”!!”を記述します。
ただし、値がnullの場合は例外が発生します。

var test4: String? = "eee"
var test4b: String = test4!! // OK
test4 = null
try {
  test4b = test4!! // Exception
} catch (ex: Exception) {
  System.out.println("test4 is null");
}

自動キャスト

通常、null許容型の変数のメソッドを呼び出す場合は”?.”を使用しますが、先にif文なのでnullチェックをしている場合、以降はnull非許容型にキャストされます。このため”?.”は不要になります。Kotlinは賢いので。
var test5: String? = "fff"
var test5b = ""
if (test5 != null) {
  test5b = test5.toUpperCase()
  //test5_2 = test5?.toUpperCase() // 上のif文でnullチェックしているため?.は不要
}

Elvis演算子

Kotlinには三項演算子がない(えっ)のでaaa = (aaa != null)? aaa.toUpperCase(): null;のような書き方はできません。
そのかわり、”?:”(Elvis演算子)で変数がnullの場合に別の値を返すことができます。
なお、Elvis演算子には値以外にthrowやreturnも記述できます。
注意点としてif(aaa == null){ throw … } のようにnullチェックと1行の処理を書くとコンパイルで警告が出る場合があります。
この場合はElvis演算子を使用しましょう。

var test6: String? = null
var test6b = test6 ?: "ggg"
System.out.println("test6b=$test6b");

var test6c: String? = null
if (test6c == null) { // Compile Warning
  throw Exception("test6d is null")
}

test6c ?: throw Exception("test6c is null") //OK

参考

Null Safety – Kotlin Programming Language

伊藤 |

« »
このページのトップへ