Java 8のOptionalを引数で使用してはいけない理由 質問する

Java 8のOptionalを引数で使用してはいけない理由 質問する

多くの Web サイトで、Optional は戻り値の型としてのみ使用し、メソッドの引数では使用すべきではないと読みました。その理由を論理的に見つけるのに苦労しています。たとえば、2 つのオプション パラメータを持つロジックがあります。したがって、メソッド シグネチャを次のように記述するのが理にかなっていると思います (ソリューション 1):

public int calculateSomething(Optional<String> p1, Optional<BigDecimal> p2) {
    // my logic
}

多くの Web ページでは、Optional をメソッド引数として使用してはならないと指定しています。これを念頭に置いて、次のメソッド シグネチャを使用し、引数が null になる可能性があることを指定する明確な Javadoc コメントを追加して、将来の保守担当者が Javadoc を読んで、引数を使用する前に常に null チェックを実行することを期待します (ソリューション 2)。

public int calculateSomething(String p1, BigDecimal p2) {
    // my logic
}

あるいは、メソッドを 4 つのパブリック メソッドに置き換えて、より優れたインターフェイスを提供し、p1 と p2 がオプションであることをより明確にすることもできます (ソリューション 3)。

public int calculateSomething() {
    calculateSomething(null, null);
}

public int calculateSomething(String p1) {
    calculateSomething(p1, null);
}

public int calculateSomething(BigDecimal p2) {
    calculateSomething(null, p2);
}

public int calculateSomething(String p1, BigDecimal p2) {
    // my logic
}

ここで、各アプローチに対してこのロジックを呼び出すクラスのコードを書いてみます。まず、 を返す別のオブジェクトから 2 つの入力パラメータを取得しOptional、次に を呼び出しますcalculateSomething。したがって、ソリューション 1 を使用する場合、呼び出しコードは次のようになります。

Optional<String> p1 = otherObject.getP1();
Optional<BigInteger> p2 = otherObject.getP2();
int result = myObject.calculateSomething(p1, p2);

ソリューション 2 を使用する場合、呼び出しコードは次のようになります。

Optional<String> p1 = otherObject.getP1();
Optional<BigInteger> p2 = otherObject.getP2();
int result = myObject.calculateSomething(p1.orElse(null), p2.orElse(null));

ソリューション 3 を適用する場合、上記のコードを使用することも、次のコードを使用することもできます (ただし、コードが大幅に増えます)。

Optional<String> p1 = otherObject.getP1();
Optional<BigInteger> p2 = otherObject.getP2();
int result;
if (p1.isPresent()) {
    if (p2.isPresent()) {
        result = myObject.calculateSomething(p1, p2);
    } else {
        result = myObject.calculateSomething(p1);
    }
} else {
    if (p2.isPresent()) {
        result = myObject.calculateSomething(p2);
    } else {
        result = myObject.calculateSomething();
    }
}

Optionalそこで私の質問は、なぜメソッドの引数として sを使用するのは悪い習慣だと考えられているのかということです(解決策 1 を参照)。これは私にとって最も読みやすい解決策のように見えますし、将来のメンテナーにとってパラメータが空/null になる可能性があることを最も明白にします。( の設計者がOptional戻り値の型としてのみ使用することを意図していたことは承知していますが、このシナリオで使用しない論理的な理由は見つかりません)。

ベストアンサー1

ああ、それらのコーディングスタイルは、少し疑ってかかるべきです。

  1. (+) セマンティック分析を行わずに、Optional の結果を別のメソッドに渡すこと (メソッドに任せる) はまったく問題ありません。
  2. (-) メソッド内で条件付きロジックを引き起こすオプション パラメータを使用することは、文字通り逆効果です。
  3. (-) 引数を Optional にパックする必要があるため、コンパイラにとって最適ではなく、不要なラッピングが行われます。
  4. (-) null 許容パラメータと比較すると、Optional はコストがかかります。
  5. (-) 実際のパラメータで Optional を null として渡すリスク。

一般的に、Optional は、解明する必要がある 2 つの状態を統合します。したがって、データ フローの複雑さを考えると、入力よりも結果に適しています。

おすすめ記事