[解決済み] なぜJava 8のOptionalは引数で使ってはいけないのか
質問
多くのWebサイトで、Optionalは戻り値の型としてのみ使用し、メソッドの引数には使用すべきではないと書かれています。 論理的な理由がわからず困っています。 例えば、2つのオプションのパラメータを持つロジックがあります。 したがって、私はこのようにメソッドのシグネチャを書くのが理にかなっていると思います(解決策1)。
public int calculateSomething(Optional<String> p1, Optional<BigDecimal> p2 {
// my logic
}
多くの Web ページでは、Optional をメソッドの引数として使用しないよう指定しています。このことを念頭に置いて、私は以下のメソッドシグネチャを使い、Javadocのコメントを追加して、引数がNULLである可能性があることを明記することができます。
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
をメソッドの引数として使用することができますか (解決策 1 を参照)?
私にとっては最も読みやすい解決策に見えますし、将来のメンテナにとってパラメータが空/nullになりうることが最も明白になります。 (私は
Optional
これは戻り値としてのみ使用されることを意図していますが、このシナリオで使用しない論理的な理由は見当たりません)。
どのように解決するのですか?
ああ、そういうコーディングスタイルは、ちょっと塩梅がいいんですよ。
- (+) Optionalの結果を意味解析せずに他のメソッドに渡すこと; メソッドに任せることは、全く問題ありません。
- (-) メソッド内部で条件ロジックを引き起こすOptionalパラメータを使用することは、文字通り逆効果です。
- (-) 引数を Optional に入れる必要があるのは、コンパイラにとって最適とは言えず、不必要な折り返しをしてしまいます。
- (-) null可能なパラメータと比較して、Optionalはよりコストがかかる。
- (-) 実際のパラメータで、誰かが Optional を null として渡す危険性がある。
一般的には オプショナルは2つの状態を統合し、それを解かなければならない。したがって、データフローの複雑さのために、入力よりも結果に適しています。
関連
-
この行に複数のマーカーがある - HttpServletResponseが型エラーに解決できない
-
このラインで複数のマーカーを解決する方法
-
[解決済み] serialVersionUIDとは何ですか、またなぜそれを使用する必要がありますか?
-
[解決済み] なぜJavaにはtransientフィールドがあるのですか?
-
[解決済み] 特定のUnicode文字を含むコメントでのJavaコードの実行が許可されているのはなぜですか?
-
[解決済み] Javaオプションパラメータ
-
[解決済み] Java の assert キーワードは何をするのか、そしていつ使うべきなのか?
-
[解決済み】array[idx++]+="a "は、Java 8ではidxを1回増やすが、Java 9と10では2回増やすのはなぜか?
-
[解決済み】Java 8のゲッターはオプションの型を返すべきですか?
-
[解決済み】Java 8のOptional.ifPresentとif-not-Presentの機能的なスタイル?
最新
-
nginxです。[emerg] 0.0.0.0:80 への bind() に失敗しました (98: アドレスは既に使用中です)
-
htmlページでギリシャ文字を使うには
-
ピュアhtml+cssでの要素読み込み効果
-
純粋なhtml + cssで五輪を実現するサンプルコード
-
ナビゲーションバー・ドロップダウンメニューのHTML+CSSサンプルコード
-
タイピング効果を実現するピュアhtml+css
-
htmlの選択ボックスのプレースホルダー作成に関する質問
-
html css3 伸縮しない 画像表示効果
-
トップナビゲーションバーメニュー作成用HTML+CSS
-
html+css 実装 サイバーパンク風ボタン
おすすめ
-
スレッド "main "での例外をEclipseで解決 java.lang.Error: 未解決のコンパイル問題、コンパイラとパッケージの不整合
-
IllegalArgumentException この例外を解決する方法
-
eclipse で「アクセス制限: タイプ 'HttpServer' は API ではありません」というプロンプトが表示される。
-
プロジェクトの依存関係を解決できなかった 解決
-
SocketTimeoutExceptionの解決方法です。読み込みがタイムアウトした
-
java -serverコマンドで「Error: no `server' JVM at ... jvm.dll」を解決する方法です。
-
[解決済み] Javaオプションパラメータ
-
[解決済み] Nullableアノテーションの使用方法
-
[解決済み】オプショナルの使用方法
-
[解決済み】Java 8のゲッターはオプションの型を返すべきですか?