JavaRush /Java Blog /Random-JA /コーヒーブレイク#161。Java で Optional を使用して Null を処理する方法

コーヒーブレイク#161。Java で Optional を使用して Null を処理する方法

Random-JA グループに公開済み
出典: Medium この記事は、Java コードを操作する際の Optional の目的をより深く理解するのに役立ちます。 コーヒーブレイク#161。 Optional - 1 を使用して Java で Null を処理する方法初めて Java コードを扱い始めたとき、Optional を使用するようによく勧められました。しかし当時は、なぜ null 値の処理を実装するよりも Optional を使用する方が優れているのか、ほとんど理解していませんでした。この記事では、私たちが Optional をもっと使用すべきだと思う理由と、コードの品質に悪影響を与えるコードの過剰な最適化を避ける方法を共有したいと思います。

オプションとは何ですか?

Optional パラメーターは、オブジェクトを運び、さまざまな API でnull参照を処理できるようにするために使用されます。コードスニペットを見てみましょう。
Coffee coffee = new Coffee();
Integer quantity = coffee.getSugar().getQuantity();
Sugarオブジェクトのインスタンスから砂糖を取得するCoffeeインスタンス があります。数量値がCoffeeコンストラクターに設定されていないと仮定すると、Coffee.getSugar().getQuantity() はNullPointerExceptionを返します。もちろん、いつでも古き良きNullチェックを使用して問題を解決できます。
Coffee coffee = new Coffee();
Integer quantity = 0;
if (coffee.getSugar() != null) {
  quantity = coffee.getSugar().getQuantity();
}
今はすべてうまくいっているようです。ただし、Java コードを作成する場合は、 nullチェックの実装は避けた方がよいでしょう。Optional を使用してこれを行う方法を見てみましょう。

作成方法 オプション

オプションのオブジェクトを作成するには 3 つの方法があります。
  • of(T value) — オプションの非 null オブジェクトのインスタンス化。of()を使用してnullオブジェクトを参照すると、NullPointerExceptionがスローされることに注意してください。

  • ofNullable(T value) - null を指定できるオブジェクトのオプションの値を作成します。

  • empty() - nullへの参照を表す Optional インスタンスを作成します。

// пример использования Optional.of(T Value)
String name = "foo";
Optional<String> stringExample = Optional.of(name)
// пример использования Optional.ofNullable(T Value)
Integer age = null;
Optional<Integer> integerExample= Optional.ofNullable(age)
// пример использования Optional.empty()
Optional<Object> emptyExample = Optional.empty();
これで、Optional オブジェクトが完成しました。次に、Optional の 2 つの主な方法を見てみましょう。
  • isPresent() - このメソッドは、Optional オブジェクトに null 以外の値が含まれているかどうかを示します。

  • get() - 現在の値を使用して Optional の値を取得します。空の Optional でget()を呼び出すとNullPointerExceptionが発生することに注意してください。

Optional を使用するときにget()isPresent()のみを使用する場合は、チャンスを逃すことに注意してください。これを理解するために、上の例を Optional で書き直してみましょう。

オプションによる Null チェックの改善

では、上記のコードをどのように改善できるでしょうか? Optional を使用すると、 isPresent()を使用してオブジェクトの存在を理解し、 get()を使用してそれを取得できます。まずは、isPresent()メソッドを使用して、 Coffee.getSugar()の結果をOptional でパッケージ化します。これは、 getSugar() がnull を返すかどうかを判断するのに役立ちます。
Coffee coffee = new Coffee();
Optional<String> sugar = Optional.ofNullable(coffee.getSugar());
int quantity = 0;
if (sugar.isPresent()) {
  Sugar sugar = sugar.get();
  int quantity = sugar.getQuantity();
}
この例を見ると、 coffee.getSugar() の結果をOptional にパッケージ化しても、価値が追加されるわけではなく、むしろ手間がかかるように見えます。Optional クラスのお気に入りの関数を使用することで、結果を改善できます。
  • map(Function<? super T,? extends U> マッパー) - Optional に含まれる値を指定された関数にマップします。Optional パラメーターが空の場合、map() はOptional.empty()を返します。

  • orElse(T other) は、get()メソッドの「特別な」バージョンです。Optionalに含まれる値を取得できます。ただし、空の Optional の場合は、 orElse()メソッドに渡された値が返されます。

このメソッドは、Optional インスタンスに含まれる値を返します。ただし、Optional パラメーターが空の場合、つまり値が含まれていない場合、orElse() はメソッド シグネチャに渡された値 (デフォルト値として知られる) を返します。
Coffee coffee = new Coffee();

Integer quantity = Optional.ofNullable(coffee.getSugar())
    .map(it -> it.getQuantity())
    .orElse(0);
これは本当に素晴らしいことです - 少なくとも私はそう思います。ここで、空の値の場合にデフォルト値を返したくない場合は、何らかの例外をスローする必要があります。 orElseThrow(Supplier<? extends X>ExceptionSupplier) は、 Optional パラメーターに含まれる値を返すか、Optional が空の場合は例外をスローします。
Coffee coffee = new Coffee();

Integer quantity = Optional.ofNullable(coffee.getSugar())
  .map(it -> it.getQuantity())
  .orElseThrow(IllegalArgumentException::new);
ご覧のとおり、オプションにはいくつかの利点があります。
  • nullチェックを抽象化する
  • nullオブジェクトを処理するための API を提供します
  • 宣言的なアプローチで何が達成されているかを表現できるようになります

オプションを効果的に使用する方法

私の仕事では、メソッドが「結果なし」状態を返すことができる場合、戻り値の型として Optional を使用します。私は通常、メソッドの戻り値の型を定義するときにこれを使用します。
Optional<Coffee> findByName(String name) {
   ...
}
場合によってはこれは必要ありません。たとえば、 SugarクラスのgetQuantity()など、intを返すメソッドがある場合、結果が「数量がない」ことを表すnullの場合、メソッドは0を返す可能性があります。これを理解すると、CoffeeクラスのSugarパラメータはOptional として表現できると考えることができます。理論的にはコーヒーに砂糖を入れる必要がないため、一見するとこれは良いアイデアのように思えます。ただし、ここで、 Optional を使用しない場合について説明したいと思います。 次のシナリオでは、Optional の使用を避ける必要があります。
  • DTOなどのPOJOのパラメータ タイプとして。オプションはシリアル化できないため、POJO でオプションを使用すると、オブジェクトがシリアル化できなくなります。

  • メソッドの引数として。メソッドの引数がnullになる可能性がある場合、純粋なコードの観点からは、 Optional を渡すよりもnullを渡す方が望ましいと言えます。さらに、オーバーロードされたメソッドを作成して、null メソッド引数の欠如を抽象的に処理することができます。

  • 欠落している Collection オブジェクトを表すため。Collection は空になる可能性があるため、値のない Collection を表すには、空のSetまたはListと同様に空のCollectionを使用する必要があります。

結論

Optional は、Java ライブラリへの強力な追加機能になりました。これは、存在しない可能性のあるオブジェクトを処理する方法を提供します。したがって、乱用の罠に陥らないようにメソッドを開発する際には、この点を考慮する必要があります。はい、null チェックと null 処理を実装する優れたコードを作成できますが、Java コミュニティは Optional を使用することを好みます。欠損値の処理方法を効果的に伝達し、面倒な Null チェックよりもはるかに読みやすく、長期的にはコードのバグが少なくなります。
コメント
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION