OptionalOrElseGet

WARNING

Performance

View source code on GitHub

Summary

Prefer Optional#orElseGet over Optional#orElse if the fallback requires additional computation

Suppression

Suppress false positives by adding the suppression annotation @SuppressWarnings("OptionalOrElseGet") to the enclosing element.

Disable this pattern completely by adding -Xep:OptionalOrElseGet:OFF as compiler argument. Learn more.

Samples

Replacement

Shows the difference in example code before and after the bug pattern is applied.

 import java.util.Optional;
 
 class A {
   private final Optional<Object> optional = Optional.empty();
   private final String string = optional.toString();
 
   void m() {
-    optional.orElse(string + "constant");
-    optional.orElse("constant".toString());
-    optional.orElse(string.toString());
-    optional.orElse(this.string.toString());
-    optional.orElse(String.valueOf(42));
-    optional.orElse(string.toString().length());
-    optional.orElse(string.equals(string));
-    optional.orElse(foo());
-    optional.orElse(this.<Number>foo());
-    optional.orElse(this.<String, Integer>bar());
-    optional.orElse(new Object() {});
-    optional.orElse(new int[0].length);
+    optional.orElseGet(() -> string + "constant");
+    optional.orElseGet("constant"::toString);
+    optional.orElseGet(string::toString);
+    optional.orElseGet(this.string::toString);
+    optional.orElseGet(() -> String.valueOf(42));
+    optional.orElseGet(() -> string.toString().length());
+    optional.orElseGet(() -> string.equals(string));
+    optional.orElseGet(() -> foo());
+    optional.orElseGet(this::<Number>foo);
+    optional.orElseGet(this::<String, Integer>bar);
+    optional.orElseGet(() -> new Object() {});
+    optional.orElseGet(() -> new int[0].length);
   }
 
   private <T> T foo() {
     return null;
   }
 
   private <S, T> T bar() {
     return null;
   }
 }
 

Identification

Shows code lines which will (not) be flagged by this bug pattern.
A //BUG: Diagnostic contains: comment is placed above any violating line.

import com.google.errorprone.refaster.Refaster;
import java.util.Optional;
import java.util.function.Supplier;

class A {
  private final Optional<Object> optional = Optional.empty();
  private final String string = optional.toString();

  void m() {
    Optional.empty().orElse(null);
    optional.orElse(null);
    optional.orElse("constant");
    optional.orElse("constant" + 0);
    optional.orElse(Boolean.TRUE);
    optional.orElse(string);
    optional.orElse(this.string);
    optional.orElse(Refaster.anyOf("constant", "another"));
    Optional.<Supplier<String>>empty().orElse(() -> "constant");

    // BUG: Diagnostic contains:
    Optional.empty().orElse(string + "constant");
    // BUG: Diagnostic contains:
    optional.orElse(string + "constant");
    // BUG: Diagnostic contains:
    optional.orElse("constant".toString());
    // BUG: Diagnostic contains:
    optional.orElse(string.toString());
    // BUG: Diagnostic contains:
    optional.orElse(this.string.toString());
    // BUG: Diagnostic contains:
    optional.orElse(String.valueOf(42));
    // BUG: Diagnostic contains:
    optional.orElse(string.toString().length());
    // BUG: Diagnostic contains:
    optional.orElse("constant".equals(string));
    // BUG: Diagnostic contains:
    optional.orElse(string.equals(string));
    // BUG: Diagnostic contains:
    optional.orElse(this.string.equals(string));
    // BUG: Diagnostic contains:
    optional.orElse(foo());
    // BUG: Diagnostic contains:
    optional.orElse(this.foo());
    // BUG: Diagnostic contains:
    optional.orElse(new Object() {});
    // BUG: Diagnostic contains:
    optional.orElse(new int[0].length);
  }

  private <T> T foo() {
    return null;
  }
}

Copyright © 2017-2024 Picnic Technologies BV