【Java進化史 第20回 】Java8 〜Optionalとは何か。どう読めばいいのか〜
昔は、こういうコードを何度も書いた。
User user = findUser(id); if (user != null) { String name = user.getName(); if (name != null) { System.out.println(name); } } null を確認する。
また null を確認する。
チェックを忘れれば、 NullPointerException。
仕方なかった。
当時のメソッドは、こうだったからだ。
User findUser(int id); 見つからなければ、null を返す。
だから、呼び出す側で毎回確認していた。
■ Java8では、こう書ける
Optional<User> findUser(int id); 戻り値が変わった。
null を直接返さない。
値が無い場合は、 「空の Optional」を返す。
読むときは、こう読む。
「User が入っているかもしれない箱」
■ Optionalとは何か
まずは宣言。
Optional<String> name; 意味は、
「String が入るかもしれない箱」。
値がある場合。
Optional<String> name = Optional.of("Taro"); 中身あり。
値が無い場合。
Optional<String> name = Optional.empty(); 中身なし。
これは true / false ではない。
「空の箱」を作っているだけだ。
null かもしれない値を入れる場合。
Optional<String> name = Optional.ofNullable(value); value が null なら empty。
値があれば、中身あり。
■ どう使うのか
中身があるか確認する。
if (name.isPresent()) { System.out.println(name.get()); } isPresent() は boolean を返す。
get() は中身を取り出す。
※ 中身が無いと例外になる。
デフォルト値を使う場合。
String result = name.orElse("default"); 中身があればその値。
無ければ "default"。
中身があるときだけ処理する。
name.ifPresent(n -> System.out.println(n)); 昔の
if (user != null) に近い。
■ NullPointerExceptionは減るのか
昔はこうだった。
User user = findUser(id); System.out.println(user.getName()); // NPEの可能性 Optional では、
Optional<User> user = findUser(id); そのまま user.getName() は書けない。
必ず、
isPresent()、orElse()、ifPresent()
などを通す。
だから、 nullチェック忘れの事故は減る。
ただし、 get() を乱用すれば例外は出る。
■ どこで使うのか
基本は、戻り値。
Optional<User> findUserById(int id); 見つからない可能性があるメソッド。
フィールドや引数では、あまり使わない。
■ 何が良くなったのか
「nullを返す」から、
「値が無い可能性があると宣言する」へ変わった。
その結果、
nullチェック忘れの事故が減り、 コードの意図が少し読みやすくなった。
0 件のコメント:
コメントを投稿