Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Dereference of nullable record component after checking for null #5200

Closed
xeals opened this issue Jul 12, 2022 · 0 comments · Fixed by #5205
Closed

Dereference of nullable record component after checking for null #5200

xeals opened this issue Jul 12, 2022 · 0 comments · Fixed by #5205

Comments

@xeals
Copy link

xeals commented Jul 12, 2022

Given

import org.checkerframework.checker.nullness.qual.Nullable;

class Test {
  void main() {
    checkEmpty(new Foo(""));
  }

  void checkEmpty(Foo foo) {
    if (foo.bar() != null && !foo.bar().isEmpty()) {
      System.out.println("ok");
    }
  }

  record Foo(@Nullable String bar) {}
}

Using Checker Framework v3.22.2, Java 17, and the nullness checker, I get:

java: [dereference.of.nullable] dereference of possibly-null reference foo.bar()

Expectations

Record components are implicitly final, so the value of bar() is consistent across invocations. The checker should be able to infer this.

While the issue arises due to treatment of record components as methods, the typical behaviour is similar to accessing a final field, which behaves as one would expect. The exception is where components are overridden, where a developer may introduce impure or external effects.

Alternatives

Multiple workarounds already exist:

  • Assigning foo.bar() to a variable:
String f = foo.bar();
if (f != null && !f.isEmpty()) {
// ...
  • Overriding bar() to annotate it as @Pure:
record Foo(@Nullable String bar) {
  @Override
  @Pure
  public @Nullable String bar() {
    return bar;
  }
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants