レガシーコードとは縁のないOptional
最近初めて業務で使ってうれしくなっちゃったので、次からも使えるように使用例のメモです。
2019年の完全新規案件でJava1.6を強制されることのある現場に在籍しています。
この期に及んでJava8に触れる機会があまりありません。
そんな中で「Java8からはnullチェックが簡単に書けるらしい」というJava8登場時に聞いた情報で書きました。
一応複数のサイトを確認して書いていますが、マサカリとか改善方法とかがありましたら、ぜひコメントをお願い致します。
(私のコードレビューが可能なレビュアーが案件に不在のため)(他のメンバーのレビューは私がしています)
get
について
使いどころがわからなかったので、使っていません。
いくつかサイトを見ると「get
使うな論」を見かけたので、逆に正解だったのでは?感ある。
注意
「Optionalは単純に従来のnullチェックを置換できる」は正しい認識ではありませんでした。
「Optionalを使うとnullチェック忘れの可能性撲滅のためにnullチェックを強制できる」が正しいですね…
なのでサンプルコードは動きますが、Optionalの使い方としては正しい認識のもと書かれたコードではありません。
忘れないためにこの記事は削除せずに残しますが、「Optional初めて~!」な私みたいな方は引っかからないようにお気を付けください。
@sikani さん、ありがとうございました!やっぱり有識者にレビューしてもらわないとダメだ…
Optionalで書くことを他人のレビュー指摘で挙げてなかったのが不幸中の幸い。(Java8っぽいコードを強制されない案件なので)
サンプルコード
Java1.6はわざとアレな書き方をしています。Java8はすっきり書けますね
Java8の方は**ちょっと使い方間違ってるけど。**
~~Java1.6でも三項演算子でワンライナーで書けますけどもね…retは無駄なだけだしアーリーリターンすらもせずにif~else使うしprivateメソッドも切らないで毎回if文書いてるタイプの現場でまじイケてないレガシーコードが大半なので、リファクタリングでいつも心が死ぬ。更に言うとJava8使ってもJava1.6の書き方そのままのメンバー多すぎて最早笑う。自分を意識高い系と誤解しそうになるので困る…最近賑わってた格上格下論争を思い出します。~~愚痴ですまない。
public String toStringIfNotNull(final Object obj) {
String ret;
if (obj == null) {
ret = null;
} else {
ret = obj.toString();
}
return ret;
}
public String toStringIfNotNull(final Object obj) {
return Optional.ofNullable(obj).map(Object::toString).orElse(null);
}
nullチェックの代わりにOptionalを使うなら、of
よりもofNullable
とorElse
の組み合わせが最適解なのではないかな!?という印象。
nullじゃなければ元の値をそのまま返すのであれば、map
とか中間処理?が不要になるだけですし。
map
の他には、filter
とflatMap
があります。
filter
はnullとfilter結果がfalseの場合にorElse
の引数が返ります。
flatMap
はnullの場合はorElse
の引数が返りますが、flatMap処理の結果がnullの場合、NullPointerExceptionがスローされます。(map
の場合は処理結果がnullでもorElse
の引数が返る)
nullかどうかで値を返すのではなく処理を分岐する場合は、if (Optional.ofNullable(obj).isPresent())
って書けば大丈夫らしいぞ!
また、isPresent
は真偽値が返るだけですが、ifPresent
にして引数でラムダ式を渡せば、null以外の時のみ引数のラムダ式を実行、という風に書けるそうな。
まあでもJava7以降であれば、isPresentよりif (Objects.isNull(obj))
(nonNull)で分岐したほうがすっきり書ける気はするけど。
ここまで書いて気付いたけど、サンプルコードの処理内容なら、Objects.toString(obj, null)
(StringUtils.defaultStringみたいなやつ)でよかったね…確認不足でした。