はじめに
Javaでコードレビューを受けていると、一度はこんな指摘を受けたことがある人も多いのではないでしょうか。
「ここ、Objects.isNull() の方がいいですね」
正直なところ、
「え?何が違うの?」
「どっちが正解なの?」
とモヤっとしがちなポイントです。
この記事では、
- == null と Objects.isNull() の違い
- なぜ「Objects.isNull()派」が存在するのか
- 実務での一番無難な立ち回り
を整理します。
結論
技術的な優劣はありません。ほぼ好み(+チーム文化)です。
それぞれ何をしているのか
== null
if (obj == null) {
// nullチェック
}
- Javaにおける最も基本的なnull比較
- 参照が null かどうかを直接比較
- シンプルで分かりやすい
Objects.isNull()
if (Objects.isNull(obj)) {
// nullチェック
}
java.util.Objects に定義されたユーティリティメソッドで、
中身は実質これです。
public static boolean isNull(Object obj) {
return obj == null;
}
→ やっていることは完全に同じ
挙動・安全性・性能の違いは?
ありません。
- NPE耐性:同じ
- 判定結果:同じ
- 安全性:同じ
- パフォーマンス:== null がわずかに有利(メソッド呼び出しがない)
→「isNull() の方が安全」というのは誤解
では、なぜ Objects.isNull() を推す人がいるのか
① Stream / メソッド参照との相性
Objects.isNull() が作られた最大の理由はこれです。
list.stream()
.filter(Objects::isNull)
.forEach(System.out::println);
== null はメソッド参照にできません。
.filter(x -> x == null)
→ Stream内では Objects::isNull の方が自然
この書き方に慣れている人ほど、
「nullチェックは Objects.isNull() で統一したい」
という発想になります。
② nonNull() とセットで使いたい思想
list.stream()
.filter(Objects::nonNull)
.toList();
これを好む人は、
if (obj != null)
よりも
if (Objects.nonNull(obj))
を好む傾向があります。
→ 否定演算子(! や !=)を減らしたいという好み
③ 書き方を「揃える」ことを重視する文化
- 判定ロジックはユーティリティに寄せたい
- 比較演算子を直接書かない方がきれい
- チーム規約でそう決まっている
など、技術的理由ではなく設計美学・文化の場合も多いです。
公式・OSSの実態
- JDK公式コード
- Spring Framework
- 多くのOSS
→ if文では普通に == null が使われています
Objects.isNull() は
Stream・ラムダ向けの表現という位置づけです。
実務でのおすすめ使い分け
基本方針
通常の if 文
→ == null
Stream / メソッド参照
→ Objects::isNull / Objects::nonNull
チーム規約がある場合
→ 迷わず従う(正解より摩擦回避)
例
// 通常ロジック
if (user == null) {
throw new IllegalArgumentException();
}
// Stream
users.stream()
.filter(Objects::nonNull)
.forEach(this::process);
レビューで角が立たない考え方
この話題は正しさの議論にすると荒れがちです。
無難なのは、
「Streamと書き方を揃える意図ですか?」
と、思想の話に寄せること。
まとめ
== null と Objects.isNull() に機能差はない
Objects.isNull() は Stream向け表現
それ以外は ほぼ好み・文化
実務では「揃っていること」が最優先
Javaは歴史が長い分、「宗派の違い」がコードに現れやすい言語です。
この手の話題は、「どっちが正しいか」より「なぜそう書いているか」を理解して使い分ける
のが一番強い選択だと思います。