Kotlinは、型システムによってnullを安全に扱うことを実現しています。デフォルトでは、どの型もnullを取ることはできません。例えば、val a: String = nullはコンパイルエラーを引き起こします。nullを代入できることを示すには、疑問符?を使用します。例えば:
val name: String? = null
Nullable型を扱うためには、以下のツールが提供されています。
?.は、オブジェクトがnullの場合にはnullを返し、そうでない場合にはメソッド/フィールドを呼び出します:name?.length。?:を使って、左側がnullの場合にデフォルト値を設定します:val length = name?.length ?: 0if (name != null) { println(name.length) }
nullの場合にNullPointerExceptionをスローして強制的に値を取得します(非常に注意して使用します):val length = name!!.length
ベストプラクティス: Nullable型を最小限に抑え、セーフコールとエルビス演算子を使用し、!!を避け、nullが許可される状況を明示的にモデル化します。
val a: String型にnull値を代入できますか、またそれをどう回避しますか?
答え: いいえ、Kotlinではデフォルトで型はnullに等しくなることはできません。nullを代入できるようにするには、明示的にval a: String? = nullを指定する必要があります。?のない型は常にnon-nullです。
事例
銀行アプリケーションのプロジェクトで、
User型の変数がクライアントの検索結果を保存していました。開発者はvar user: Userを定義しましたが、時折クライアントが見つからず、サービスがnullを返すことがありました。これがNPEを引き起こし、クラッシュが発生しました。
事例
サポート用のチャットボットでは、ユーザーのメッセージにアクセスするために
!!を使用していました(message!!.text)。メッセージは常に受信されると考えていましたが、初めての空のメッセージでボットがクラッシュしました。セーフコールを使用していれば、問題が解決されていました。
事例
モバイルアプリケーションでは、データベースからのデータが読み込まれておらず、
nullとして送信されることがありました。安全なアクセスの代わりに、開発者は直接アクセスを使用し、データが不完全な場合にすべてのケースでクラッシュを引き起こしました。