Cleaner Code with Guava Optionals and Preconditions

Working towards clean code is a priority for me when I develop software. For some time I’ve been using Google Guava for nearly all my projects. The reason is simple. Guava provides great facilities to beautify my code. Today I want to show you how I use Preconditions to avoid unnecessary if/throw statements and Optionals to improve my code semantics.

[ Need expert advice for your project? Our Developer Support is here to resolve your questions. | Find more tips on clean code on the Software Craftsmanship page. ]

Preconditions are not new. Apache Commons had similar functionality but not as clean as Guava’s solution. Preconditions are used for checking method arguments, states, etc. When a condition is false the Precondition will throw the expected exception. With expected I mean the following: when checking a state you can use Preconditions.checkState( condition ). If the condition is false it will throw an IllegalStateException. The same is true for other Preconditions like checkArgument which throws an IllegalArgumentException. Of course, working with Preconditions only makes sense when using static Imports. Let’s take a look at an example.

Given is a method which takes a List as an argument. When this method is invoked we want to check that the list is not null and it is not empty. A plain Java solution can look like this:

public void doSomething( List list ) {
  if( list == null ) {
    throw new IllegalArgumentException( "List must not be null" );
  if( list.isEmpty() ) {
    throw new IllegalArgumentException( "List must not be empty" );
  doSomethingMore( list );

When using Guava’s Preconditions the amount of code is reduced significantly. The solution looks like the one below.

public void doSomething( List list ) {
  checkArgument( list != null, "List must not be null" );
  checkArgument( !list.isEmpty(), "List must not be empty" );
  doSomethingMore( list );

This is an improvement for sure. But this approach becomes really sexy when it’s combined with Guava’s Optionals. Optionals are a concept designed to avoid the sick null concept (read this for understanding why I call it “sick”). They are basically a container for an object to avoid nullable references. For example, null is used most of the time to check if an object is there or not. And if it’s not there, an NPE occurs. The result is code like the following:

public void doSomething() {
  if( this.field == null ) {
    throw new IllegalStateException( "Field is not initialized" );

Instead of saving the object directly as a field I often use an Optional. This avoids NPEs in my code and gives it better semantics. The example above is transformed into the one below when it’s combined with Preconditions:

public void doSomething() {
  checkState( field.isPresent(), "Argument is not initialized" );

In the end it’s up to you to decide if the code is better/cleaner with Optionals and Preconditions. From my point of view it’s definitely more speakable. I would love to hear your opinion about it in a comment ;).

12 Responses to “Cleaner Code with Guava Optionals and Preconditions”

  1. Mark says:

    While that definitely seems cleaner, the code still seems smelly – business logic mixed with parameter checking (etc). Annotations might help pull non-business logic out of the method. One could still argue that there is some code smell (and i would agree) but it would be less.

  2. Hi Mark,
    as long as you don’t use any AOP based approach or do it design by contract you will propabely end in this kind of code. I agree with you that mixing things is not the best thing. Anyway, the intend of this post was only to show how to use the guava facilities. Where to do this is not an answered question.

  3. Jerome says:

    You can use
    checkNotNull( list, “List must not be null” );
    instead of
    checkArgument( list != null, “List must not be null” );

  4. Hi Jerome,
    the bad thing about checkNotNull is that it throws an NPE. I simply wanted to avoid this behaviour.

  5. Sebastien Gandon says:

    I agree with Mark, this would defenitly look better using annotation to separate the business logic with the checking of parameters.
    Even if it comes to the same result, it would visualy look different and help the reading of the code if that is the goal.

  6. Cole Markham says:

    I’ve often used org.eclipse.core.runtime.Assert to do the same thing. It has an isNotNull method as well. I don’t really see the advantage of throwing IllegalArgumentException rather than NPE as long as you get some message other than ‘null’. If you’re catching IAE in client code that just seems like bad design, so either way it’s just some unchecked exception that will get trapped higher up the stack. The Eclipse Assert methods throw a custom AssertionFailedException for isNotNull and isTrue or IllegalArgumentException for isLegal, that seems logical to me.

  7. Jens v.P. says:

    What would uncle Bob say: “In most programming languages there is no good way to deal with a null that is passed by a caller accidentally. Because this is the case, the rational approach is to forbid passing null by default. When you do, you can code with the knowledge that a null in an argument list is an indication of a problem, and end up with far fewer careless mistakes.” [Robert C. Martin: Clean Code]. I always used to check parameters (as in your first example), I even have written some Eclipse templates for that. But after reading Clean Code, I probably won’t do that anymore, and instead simply assume all parameters to be non-null. An NPE is thrown anyway, sooner or later. And in most situations, there is not much difference between an NPE and an IllegalArgumentException, is there? Besides, I will follow the rule to not use null if possible, e.g., by returning empty collections.

    I’m also thinking about using Annotation, because of Stephan’s blog post: IMHO that’s really cool and it seems to be a good way to deal with the problem, at least to me.

    But I also will have a look at Guava. The cleaner the better :-)

  8. Thomas Ferris Nicolaisen says:

    Great little article. I’ve added it to the collection here:

  9. Gabriel says:

    I like this idea of using an easy to remember method against an if-then-throw-exception idiom, however it feels unnatural to logically *negate* all conditions you used before (and it is error prone if updating old code).

    I’d like to se methods like rejectArgument(boolean,String), rejectState(), and rejectXXXXX, to maintain the SAME condition as before.

  10. Mark says:

    Yeah, my comment was just “thinking out loud”. I am not sure there is any good solution. I was thinking the same thing about AOP. I did some digging and found some options but not sure how much better they are.
    The reason I responded was because i recently did a code review in which the first 10 (give or take) where just checking the parameters. The code obfuscated the actual business logic. And honestly, most of the time there would be an error and stacktrace anyway telling you where and what the error was. In addition to that he had unit tests to ensure the methods threw all of the [runtime] errors for parameter checking. Typically these errors will be design (development) time and not run time. I think the better way would be to design your API so that you have overloaded methods – See Martin Fowlers “Refactoring”, page 285. Of course, sometimes you DO need to check parameters and then you should. :)

  11. Hi Mark,
    don’t get me wrong, I’m also not a fan of mixing up things. But one thing comes into my mind when thinking about it:

    When I write a framework, library or any other reusable component my goal is always to keep things small and simple. Another thing is to program defensive (This does not mean checking absolutely everything). When I write such a component I don’t want to have dependencies to any AOP framework and I probably don’t want the dependencies to guava neither.

    Currently I’m writing a server based OSGi application and I’m using the approach described in the post because most AOP solutions I found are using byte code manipulation and I don’t want to use them too (I’m aware of the proxy based solution).

    I also have to say that the approach that Jens has described is a valid solution. But only if you life in a closed environment. When writing frameworks this is not an option from my point of view. Also I think throwing NPE’s instead of IAE’s is not a good thing because null is a sick concept. When a NPE occurs this can mean that the user has done something wrong or the framework internally. When throwing an IAE it’s clear that the API was used not correctly.

    The coolest solution would a design by contract concept. But it hink we are currently not there, at least with my current state of knowledge.

    Thanks for this great discussion guys. These are just my 5 cents ;)

  12. Mark says:

    Holger, I can see the need for better information if the user of the API does not have the source. What i would liked to see in code though would be:

    public void doSomething( List list ) {

    I too think this discussion is great. I think it shows there is no easy answer and that we need to think about things. Not just randomly apply patterns based on what we think we know or read (which was the case of the developer that I mentioned). Now if someone would recreate Guava in .NET….

12 responses so far

Written by . Published in Categories: Planet Eclipse

Looking for a job?

Karlsruhe / Remote
Karlsruhe / Victoria / Remote
Karlsruhe / Victoria / Remote