ENGINEER BLOGPhone Appliのエンジニアブログ

Kotlin 紹介 - Null Safety

2020年9月 4日

はじめに

弊社プロダクトの「連絡とれるくん」では、サーバサイドに Kotlin を採用しています。

Kotlin 採用理由の 1 つに Null Safety があります。
採用当初はあった方がよさそうくらいの感覚だったのですが、使い続けてみて null の概念のある静的型付け言語には無くてはならないもの、に変わってます。
そんな Null Safety について開発経験を基に紹介します。

【目次】
・ Null Safety とは
・ なぜ null を管理したいか
・ 基本は non-null type
・ Kotlin の Null Safety で気を付けるべきこと
・ 終わりに

Null Safety とは

公式ドキュメント にある通りなんですが、簡単に言うと

・ null を代入できる型 nullable type
・ null を代入できない型 non-null type

の 2 つに分けて null をうまい具合に管理することです。
01.png

なぜ null を管理したいか

null とはすべての参照型に代入可能な便利なものです。
初期値やデフォルト値にできます。

ただ、すべての参照型に代入できるということは、制約が無さすぎるのです。

静的型付け言語のメリットの 1 つは、継承関係の無い型 A から型 B への代入をコンパイルエラーで防げること(つまり制約になる)です。
null はこの制約にとらわれないジョーカーのようなものです。
02.png
non-null type があると、 null に対して制約を課せます。

関数による例

例えば、参照型の引数を 1 つ持つ関数の実装を考えてみます。
参照型の引数は null の可能性があるため、 null についての振る舞いも設計します。
(もちろん null を考慮しないまま実装して NullPointerException が発生したら、その時はスタックトレースから調査、という方針もありますが・・・)
引数が null の場合の振る舞いとしては大体下記になると思います。
・ IllegalArgumentException を投げる
・ 何もしないで終わる (戻り値があるなら null を返す)
・ null を何らかのデフォルト値に置換して、処理を行う
14-03.png

ここで non-null type の引数にすれば、関数側の null についての振る舞い設計が不要になり、関数本来の機能に集中できます。
14-04.png

基本は non-null type

関数の引数を non-null type にしても、関数の呼び出し側で null 除外する手間は残ってます。
Kotlin には null 除外のための便利な機能 ?. / ?: がありますが、手間であることには変わりないです。

関数の呼び出し側、つまりコード全体で non-null type を使うようにすれば、null 除外の手間は減ります。
どうしても nullable type を使わなければならない箇所は存在しますが、そこだけ気を付けて null 除外すれば Null Safety なコードになっていきます。

Kotlin の Null Safety で気を付けるべきこと

Kotlin on JVM の場合、 Java のライブラリを簡単に使用可能です。
Java のライブラリから取得できる値 (メソッドの戻り値など) は、 nullable typenon-null type 両方の可能性がある platform type というものになります。
※ ただし 決められた @NotNull / @Nullable アノテーション が付いていれば nullable typenon-null type に明確に分かれます

platform type は、 non-null type の可能性があるため null 除外処理が無くてもコンパイルは通りますが、 nullable type の可能性があるため null である可能性は十分にあります。
14-05.png

もやっとする話なんですが、ようは @NotNull / @Nullable アノテーションを明示していない Java ライブラリは、コンパイラによる Null Safety の支援は受けられないので、ライブラリの仕様を理解して使うしかない、ということです。

終わりに

Null Safety について感じていることを言語化してみました。
最初に書いたとおりなんですが、 null の概念のある静的型付け言語は nullable type / non-null type の使い分けはできて当たり前、と思うようになってます。

今後、他の言語を採用することになっても、 Null Safety の有無は大きな判断基準の 1 つになると思います。
個人的に好きな言語である C# は 8.0 から Null 許容参照型 が導入されてて嬉しいです。



書いた人: プロダクトデベロップメント部 藤本泰輔