# Optional false positive in method chains

**URL:** <https://community.sonarsource.com/t/optional-false-positive-in-method-chains/46983>\
**Category:** Report False-positive / False-negative...\
**Tags:** java\
**Created:** [July 23, 2021, 10:53pm UTC](https://community.sonarsource.com/t/optional-false-positive-in-method-chains/46983 "2021-07-23T22:53:30Z")\
**Posts on this page:** 2\
**Page:** 1

<div class="post-metadata">

**Author:** ![incident-recipient](https://dub1.discourse-cdn.com/sonarsource/user_avatar/community.sonarsource.com/incident-recipient/32/24317_2.png) [@incident-recipient](https://community.sonarsource.com/u/incident-recipient)\
**Post date:** [July 23, 2021, 10:53pm UTC](https://community.sonarsource.com/t/optional-false-positive-in-method-chains/46983/1 "2021-07-23T22:53:30Z")

</div>

**Summary** :

Optionals that are checked with `isPresent()` in a method chain do not seem to be detected and throw warnings when get() is called on the line immediately after. With classes that possess a lot of optionals it is not practical to assign each to their own variable to avoid this warning.

**Rule:**  
Call “Optional#isPresent()” before accessing the value

**Environment:**

- versions used: SonarQube (Community Edition Version 9.0 (build 45539)
- minimal code sample to reproduce (with analysis parameter, and potential instructions to compile).
- Java

**Code Sample:**

```auto
if (feature.getLongDescription().isPresent()) { pickleJarBuilder.withLongDescription(feature.getLongDescription().get());

```

---

<div class="post-metadata">

**Author:** ![Michael](https://dub1.discourse-cdn.com/sonarsource/user_avatar/community.sonarsource.com/michael/32/43_2.png) [@Michael](https://community.sonarsource.com/u/Michael)\
**Post date:** [August 6, 2021, 8:24am UTC](https://community.sonarsource.com/t/optional-false-positive-in-method-chains/46983/4 "2021-08-06T08:24:59Z")

</div>

Hello @incident-recipient,

What you are facing is a known issue, and we have no ways to avoid it except by, like you said, storing the result of the optional call to a variable. We however have this ticket to try to make it explicit in the rule message and description: [SONARJAVA-3881](https://jira.sonarsource.com/browse/SONARJAVA-3881)

The “_FPs_” you report exist because we consider that two distinct calls to methods are potentially returning different values. On our side, we don’t consider them as FP.

Concretely, in the following code, we would consider that `o1` and `o2` could be different. It’s not necessarily true, but it’s not necessarily false as well.

```java
Object o1 = foo();
Object o2 = foo();

```

We actually have no easy way to know what’s the internal behavior of the `foo()` method (is it related to the state of its owning object? is it the same object being returned systematically? is there any other means to change the returned value without calling `foo()`?). Considering that its two distinct values guarantee that we will not recommend wrong fixes and raises FPs for many rules. However, this model still causes noise for some rules, and in particular in S3655 with methods returning _the same_ Optionals.

The following code, similar to yours, will raise an issue that could be considered as FP, but only if `myOptional()` returns always the same optional (which goes with [other concerns as soon as you want to store it as a field](https://stackoverflow.com/questions/29033518/is-it-a-good-practice-to-use-optional-as-an-attribute-in-a-class)):

```java
if (myOptional().isPresent() 
  && "hello".equals(myOptional().get())) // FP call isPresent() before calling get()

```

While Optionals are immutable, I still don’t manage to see it as a False Positive. We can not guarantee that it’s the same optional which will be returned between two method invocations. When no arguments are provided, we could expect that the method would act as a getter… but then it raises again some other problems. How to differentiate the following situation with a static-analysis engine?

```java
boolean foo(MyObject a, MyObject b) {
  return a.myOptional().isPresent() && b.myOptional.get() > 42;
// ^ 'a' is not the same as 'b' ^
}

```

A way to reduce the noise could be to consider that consecutive calls without arguments to a method returning an Optional actually return the same Optional… but this approximation could also lead to False Negatives… and ultimately bugs in your code. A risk that we don’t want to take.

**I would therefore recommend marking your issues as “Won’t Fix” if you disagree with them.**

Note that If you are doing this operation in many many places, I would even rather opt for another approach and a dedicated consumer:

```java
import java.util.Optional;
import java.util.function.Consumer;
import java.util.function.Supplier;

public class Utils {
  static <T> void consume(Supplier<Optional<T>> supplier, Consumer<T> consumer) {
    supplier.get().ifPresent(value -> consumer.accept(value));
  }
}

```

And your code would be:

```java
Utils.consume(feature::getLongDescription, pickleJarBuilder::withLongDescription);

```

Cheers,  
Michael
