-
Notifications
You must be signed in to change notification settings - Fork 6
Our mission
The goal of this tutorial is to learn how to use the Checker Framework, and specifically the Nullness Checker on a real-life project.
Ideally, once we’re done we can be sure that our code is safe from
NullPointerException
s.
The Nullness Checker’s promise is that once it
issues no warnings for a given program, then running that program will never throw a null pointer exception.
To keep that promise it needs a little help from us, the programmer. We need to
make some of our knowledge of nullness in the program explicit by annotating
types as either
@Nullable
(possibly null
) or
@NonNull
(never null
). So, the signature of makeSlug
from the introduction is really
public static @NonNull String makeSlug(@NonNull String s)
and the signature of getTitle
, if it might return null
, is properly
public @Nullable String getTitle()
In a sense, these annotations are like an additional, refined type system placed
on top of the Java one. Something that has a type that includes the null
value
(the result of getTitle
, @Nullable String
) is evidently not compatible with
a type that cannot hold a null
value (the argument of makeSlug
, @NonNull String
). We can think of these annotations as constituting a ‘pluggable type
system’. The Nullness Checker operates by checking that the program is type-safe
with respect to nullness.
Now, it would be pretty tedious if we had to annotate every reference type in
our code as either @Nullable
or @NonNull
. As a convenience, the Nullness
Checker makes a reasonable default assumption about references: every
unannotated reference is assumed to be @NonNull
.
Just to make sure we’re on the same page, a quick word on why assuming
@NonNull
by default makes sense: let’s talk about null-safe programming
practice.
The first rule of null-safe programming is don’t use null
.
Simply put, if you don’t use null
you won’t get NullPointerException
s.
Experience tells us that code that doesn’t need to deal with null
references
is not only safer, but also more concise. Others have explained this
well. A
number of strategies exist to avoid using null
, such as using null-objects
instead, returning empty collections or
Optional
instead of null
, failing fast when receiving null
arguments, and insisting
on limiting the scope of nullable references where they cannot be avoided. Check
the References for more on this topic.
Now, not using null
and making this a guiding principle enables a very useful
assumption about the nullness of all references. We can assume that by default,
references are not null
. The marked case that we want to stand out in code is
really the nullable reference. That’s where we must be on our toes and guard
against attempts to dereference it. That’s where an annotation, @Nullable
, is
warranted.
Helpfully, the Nullness Checker shares this attitude towards nullability. In the
world view of the Nullness Checker, every type use carries an implicit
@NonNull
annotation. Nullable references need to be marked up as @Nullable
.
We’ll be reminded of this a couple of times in the course of this tutorial.
In real-world programming projects, maintaining a null-hostile position isn’t
always practical, unfortunately: especially when dealing with legacy code, we
often find null
to be used awfully expansively. One of the more interesting
questions we’re going to answer in this tutorial, is how null-safe programming
practice, enforced at compile time works out on a real-world project: are we
going to see an explosion of annotations, degrading the readability of our code?
Enough theory, let’s get started.
So, our mission is to learn how to use the Nullness Checker, and we’re going to learn this by integrating it into a real-world (work with me) project.
We’re going to use a snapshot of the Spring Framework’s Pet Clinic sample web app.
The Pet Clinic is perhaps not the most appealing project, but it does have some characteristics that make it a good candidate.
- The Pet Clinic has some typical enterprisey bits to it which many programmers must (for better or worse) work with every day.
- The Pet Clinic is a typical legacy software project. There is bound to be some shoddy code in there and that’s for the Checker Framework to chew into.
Ok, on to checking out the code and setting up the project on the next page.