Proposal: ForbidNull

138 views
Skip to first unread message

Martin Grajcar

unread,
Sep 10, 2015, 2:58:51 AM9/10/15
to project...@googlegroups.com
Looking at my code, I can see tons of fields annotated with @Nonnull and just a few fields with @Nullable or without either annotation. This feels wrong.

I'm using @lombok.Nonnull for what it does, @javax.annotation.Nullable as documentation and I'm not very consequent about it. And it's hard to be. The nearly omnipresent @Nonnull adds quite some boilerplate and I'd be more happy if I could leave it out.

So I'm proposing @ForbidNull which can be applied class-wide and makes all fields, method arguments and results @Nonnull, unless annotated by some @Nullable. It could look like

@ForbidNull(fields=boolean, parameters=boolean, results=boolean)

with all three flags defaulting to true (or maybe to what lombok.config says). For me, the most important part are the fields, where nearly all of them are @Nonnull. I'd like to drop all the annotations and use @Nullable for the exceptional ones. For the price of a few fail-fast NPEs during development, I could get cleaner and more reliable code.

I know that unlike a checker using @ParametersAreNonnullByDefault, Lombok can't work with inheritance, but that's not that bad. Not dealing with inheritance limits the effect of @ForbidNulls to a single class, so let's call it a feature. It only should know that equals must accept null by a contract inherited from Object.

Any thoughts?

Ryan Schmitt

unread,
Sep 10, 2015, 10:59:07 AM9/10/15
to project...@googlegroups.com
I'm not sure what you mean when you say you're not "consequent" about @Nonnull and @Nullable, but I'm wondering why @lombok.Nonnull couldn't just be generalized to classes. It already supports fields, parameters, methods, and local variables; applied to a class, it could have the semantics that you describe.

--
You received this message because you are subscribed to the Google Groups "Project Lombok" group.
To unsubscribe from this group and stop receiving emails from it, send an email to project-lombo...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Martin Grajcar

unread,
Sep 10, 2015, 5:19:06 PM9/10/15
to project...@googlegroups.com
On Thu, Sep 10, 2015 at 4:59 PM, Ryan Schmitt <rsch...@u.rochester.edu> wrote:
I'm not sure what you mean when you say you're not "consequent" about @Nonnull and @Nullable,
  • static fields: They're mostly obvious.
  • other fields:
    • Nonnull: I often use @RequiredArgsConstructor(onConstructor=@__(@Inject), access=AccessLevel.PRIVATE) and then the (final) fields are guaranteed not to be null by the injection itself, so I'm reluctant to spam them with the annotation.
    • Nullable: There's nothing forcing me to annotate them, so I often forget. I also dislike annotating all fields, some with @Nonnull, others with @Nullable, as this is boilerplate and the annotations look visually similar.
  • methods: It's important for me to keep the signatures short and adding an annotation to the methods and each parameter blows it up.
With @ForbidNull, I'd only annotate the exceptions to the non-null rule, so maybe one in ten fields/methods/parameters would get an annotation.

I'd also get rid of most of my Guava's Preconditions.checkNonNull.

but I'm wondering why @lombok.Nonnull couldn't just be generalized to classes. It already supports fields, parameters, methods, and local variables; applied to a class, it could have the semantics that you describe.

It lacks the (fields=boolean, parameters=boolean, results=boolean) arguments I'm proposing above and it shouldn't get them as they make only sense on a class (parameters and results make also sense on a method, but with them it gets too long to be worth it).

@ForbidNull is something what kills your application if misused, so I'd also prefer a new shiny name, different from all the existing ones, so that there's no single chance of confusion.

Implementation: I wonder if ForbidNullHandler could simply conditionally add @Nonnull to fields and arguments (for methods it doesn't work) to be processed by HandleNonNull later. This would make the implementation rather trivial.
Reply all
Reply to author
Forward
0 new messages