kotlinでの開発も広まって来ているせいで、android界隈でもオプショナルを使うことが当然の様になってきていると思います。
自分は、C言語でコードを書いていた頃からnullチェックが嫌いでした。外部公開I/Fとかならやるんですが、privateな関数ではnullチェックを書いたら負けかなと思っていました。
kotlinで書く場合、nullチェックをしなくてもヌルポを発生させることもないコードを簡単に書くことができます。ただ、ちょっと考えて欲しいのですが、例えば次のようなコード、ある外付けデバイスに文字列を出力するメソッドとします。
private fun foo(device: Device?, str: String) {
device?.initialize()
device?.output(str)
device?.close()
}
これって、Javaで書くならこういうことでしょう。
private void foo(@Nullable Device device, String str) {
try {
device.initialize();
device.output(str);
device.close();
} catch(NullPointerException e) {
// do nothing
}
}
もうちょっとマシに見えるかもしれない書き方なら
private void foo(@Nullable Device device, String str) {
if (device == null) return;
device.initialize();
device.output(str);
device.close();
}
どちらもヌルポで落ちることはないけれど、外付けデバイスに目的の文字列が出力されることはなく、しかも出力されない理由もよくわからないという結果になります。
引数にnullを許容する型をとっておきながら、nullを渡された場合のケアを全くしていません。JavaDocで nullが渡されたらなにもしません
と書いておけば、それで十分でしょうか?
この場合、引数をnullを許容しない型にした方が使いやすいと考えます。
private fun foo(device: Device, str: String) {
device.initialize()
device.output(str)
device.close()
}
これで、javaコードからnullが渡されればヌルポが発生し、即座に不正箇所がわかりますし、kotlinからコールする場合はコンパイラがチェックしてくれます。
これは、ちょっと極端にした例で、おそらくjavaコードに@Nonnull
や@Nullable
などのアノテーションがない状態でコンバートして、そのままなんだと思いますが…
実際にコードレビューをしていて、似た感じのコードを見ることがあるので、こんなコードを書かないようにして欲しいと思います。
参考リンク
@Nonnull
な引数のnullチェックについては、下記リンク先の考えがいいと思います。
Android: NonNullアノテーション