【Java】Optionalの使い方。Nullに怯える無能なコードを卒業せよ

【Java】Optionalの使い方。Nullに怯える無能なコードを卒業せよ Java

Javaで開発をしていて、未だに if (obj != null) を乱発している奴はいないか。

あるいは、NullPointerException(NPE)を出して「運が悪かった」などと抜かしている奴はいないか。

もしそうなら、今すぐエンジニアを廃業しろ。
NPEは不運ではなく、君の設計の甘さが招いた必然である。

Java 8で Optional が導入されてから既に長い月日が経つ。
このクラスは、単なる「Nullチェックの代用品」ではない。
「値が存在しない可能性がある」という事実を、コードの構造(型)として明示するための強力な武器だ。

この記事では、Optionalの正しい使い方と、現場で通用する「プロの流儀」を徹底的に叩き込む。
曖昧な理解でコードを書くのはやめろ。正解だけを実装しろ。

【執筆者の簡易プロフィール】
江田島 執筆者:江田島
  • 43歳男性、既婚、1児の父
  • アプリケーションエンジニア
  • 大手受託開発企業に勤務中
  • Java一筋の職人(教え方はスパルタ気味)
  • 嫌いなもの:やる気のないエンジニア

Optionalの存在意義は、Nullを「隠す」のではなく「型で示す」こと

まず根本的な勘違いを正しておく。

Optionalの目的は、Nullを消し去ることではない。
戻り値として Optional を定義することで、呼び出し側に対して「このメソッドは値を返さない可能性があるぞ」と型安全に警告することにある。

これを理解せず、すべての変数にOptionalを使うような愚行は犯すな。

Optionalは主に「戻り値」として使うべきものであり、フィールド変数や引数に使うのは設計が未熟な証拠である。

インスタンスの生成(ofとofNullableの使い分け)

Optionalのインスタンスを作るメソッドは主に3つある。
ここでの選択ミスは、そのままプログラムのクラッシュに直結する。

// 1. 値が絶対にnullではない場合
Optional<String> opt1 = Optional.of("Edajima");

// 2. 値がnullかもしれない場合
String name = getNullableName();
Optional<String> opt2 = Optional.ofNullable(name);

// 3. 空のOptionalを作る場合
Optional<String> opt3 = Optional.empty();

Optional.of(value) は、渡された値がnullだと即座にNPEを投げる。
「ここには絶対に値が入っているはずだ」という強い意志がある時のみ使え。
少しでもnullの可能性があるなら Optional.ofNullable(value) を選ぶのが鉄則だ。

適当に of を使って、実行時に落ちるようなコードを書く奴は、仕様書を読み直してから出直せ。

値の取得と処理にget()を無条件で使うのは論外

Optionalの中身を取り出す際、opt.get() を直接叩く奴がいる。

中身が空だった場合、NoSuchElementException が発生する。
これでは if (obj != null) でチェックしていた旧時代のコードと何も変わらない。

プロなら、以下のメソッドを使い分け、流れるように処理しろ。

orElseとorElseGet:評価タイミングの差を理解せよ

値がない場合のデフォルト値を指定する際、orElseorElseGet を混同するな。

// orElse:値の有無に関わらず、引数のメソッドが常に評価される
String result1 = opt.orElse(getDefaultValue());

// orElseGet:値がない時だけ、引数のLambdaが実行される
String result2 = opt.orElseGet(() -> getDefaultValue());

orElse に重い処理や副作用のあるメソッドを渡すと、値が存在していても実行されるため、パフォーマンスの低下を招く。

効率を求めるなら、基本的には orElseGet を使え。この程度の使い分けもできないエンジニアに、大規模開発を任せることはできない。

ifPresentとifPresentOrElse:条件分岐を排除せよ

値がある時だけ処理をしたいなら、if文ではなく ifPresent を使うのがモダンなJavaの流儀である。

opt.ifPresent(val -> System.out.println("値は" + val + "である"));

Java 9以降なら、ifPresentOrElse を使うことで、値がある場合とない場合の両方の挙動を、ネストなしで記述できる。

コードの可読性を上げる努力を怠るな。

Optionalの禁じ手:アンチパターンを脳に刻め

Optionalは強力だが、無能が使うと毒になる。
以下の「禁じ手」は絶対にやるな。

  • Optional型の引数を取るな! ⇒ 呼び出し側にOptionalのラップを強制させるな。nullを許容するなら、素直にオーバーロードするかアノテーションで示せ。
  • Optional.get() を安易に呼ぶな! ⇒ 値の存在が保証されない状態で呼ぶのは、ただの自爆行為である。
  • CollectionをOptionalで包むな! ⇒ 空のコレクションを返せば済む話だ。二重に「空」の状態を作るのは混乱の元でしかない。
  • Serializableではないことを忘れるな! ⇒ Optionalをフィールドに持つと、直列化(Serialization)に失敗する。

これらのルールを破ったコードがレビューに回ってきたら、私は即座に突き返す。
プロの世界に「なんとなく」は通用しない。

まとめ:Optionalはエンジニアの「責任」の表明である

JavaでOptionalを使いこなすということは、Nullという曖昧な存在に対し、エンジニアとして明確な「意思」を持つことと同義である。

戻り値にOptionalを使い、値の欠落を仕様として明示する。
インスタンス生成は ofNullable を基本とし、NPEを徹底排除する。
orElseGetifPresent を使い、宣言的に記述する。
アンチパターンを避け、コレクションやフィールドには使わない。

基本を完璧にこなせ。
それができて初めて、君はエンジニアとしてのスタートラインに立てる。
これ以上、Nullごときで時間を溶かすような真似はするな。

以上である。

コメント

タイトルとURLをコピーしました