metters
metters

Reputation: 591

Why would I use Lombok-Annotation @NonNull?

Lombok offers the annotation @NonNull which executes the nullcheck and throws a NPE (if not configured differently).

I do not understand why I would use that annotation as described in the example of that documentation:

private String name;
public NonNullExample(@NonNull Person person) {
    super("Hello");
    if (person == null) {
      throw new NullPointerException("person is marked @NonNull but is null");
    }
    this.name = person.getName();
  }

The NPE would be thrown anyway. The only reason here to use the annotation imo is if you would want the exception to be different from a NPE.

EDIT: I do know that the Exception would be thrown explicitly and thus 'controlled', but at least the text of the error message should be editable, shouldn't it?

Upvotes: 25

Views: 40156

Answers (5)

Roberto Manfreda
Roberto Manfreda

Reputation: 2623

I love lombok but in this case (personally) I prefer to use the @Nonnull annotation from javax.annotation with the Objects.requireNonNull from java.util.Objects.

Using lombok in this way make the code cleaner but even less clear and readable:

public Builder platform(@NonNull String platform) {
    this.platform = platform;
    return this;
}  

This method raises a NullPointerException (no evidence of it) and in addiction passing a null argument, in a method call, is not reported by my IDE (IntelliJ Ultimate 2020.1 EAP - latest version - with lombok plugin)


So I prefer using the @Nonnull annotation from javax.annotation in this way:

public Builder platform(@Nonnull String platform) {
    this.platform = Objects.requireNonNull(platform);
    return this;
}

The code is a little bit verbose but clearer and my IDE is capable to warning me if I pass a null argument on method call!

Upvotes: 3

Sasha
Sasha

Reputation: 4004

IMHO, you've understood that documentation page wrongly.

That documentation page doesn't imply that you are recommended to use both Lombok @NonNull annotations and explicit if (smth == null) throw …-like checks as the same time (in the same method).

It just says that a code like this one (let's call it code A):

import lombok.NonNull;

public class NonNullExample extends Something {
  private String name;

  public NonNullExample(@NonNull Person person) {
    super("Hello");
    this.name = person.getName();
  }
}

will be automatically (internally) translated by Lombok into a code like the one quoted the question (let's call it code B).

But that documentation page doesn't say that it would make sense for you to explicitly write the code B (though you are allowed; and Lombok will even try to prevent double check in this case). It just says that with Lombok you are now able to write the code A (and how it will work — it will be implicitly converted into the code B).

Note, that the code B is a “vanilla Java” code. It isn't expected to be processed by the Lombok for the second time. So @NonNull in the code B is just a plain annotation, which has no influence on the behavior (at least, not by Lombok means).

It's a separate question why Lombok works in that way — why it doesn't remove @NonNull from the generated code. Initially I even thought that it might be a bug in that documentation page. But, as Lombok author explains in his comment, @NonNulls are intentionally kept for the purposes of documentation and possible processing by other tools.

Upvotes: 3

mernst
mernst

Reputation: 8117

Writing a type annotation such as @NonNull serves several purposes.

  • It is documentation: it communicates the method's contract to clients, in a more concise and precise way than Javadoc text.
  • It enables run-time checking -- that is, it guarantees that your program crashes with a useful error message (rather than doing something worse) if a buggy client mis-uses your method. Lombok does this for you, without forcing the programmer to write the run-time check. The referenced example shows the two ways to do this: with a single @NonNull annotation or with an explicit programmer-written check. The "Vanilla Java" version either has a typo (a stray @NonNull) or shows the code after Lombok processes it.
  • It enables compile-time checking. A tool such as the Checker Framework gives a guarantee that the code will not crash at run time. Tools such as NullAway, Error Prone, and FindBugs are heuristic bug-finders that will warn you about some mis-uses of null but do not give you a guarantee.

Upvotes: 19

Shweta Gupta
Shweta Gupta

Reputation: 776

It serves similar purpose to

java.util.Objects requireNonNull()

or Guava’s PreConditions. This just makes the code more compact and fail-fast.

Upvotes: 1

Roee Gavirel
Roee Gavirel

Reputation: 19445

The idea of the annotation is to avoid the if (person == null) in your code and keep your code cleaner.

Upvotes: 2

Related Questions