27 October 2011

Preconditions - (Java) Guava Collections Library

Fail early. It is applicable in life and programming.

The methods (or functions) are inevitable part of your code. The methods operate on the objects (or state of the system) and has a logic to do. Sometimes, the logic cannot (or rather must not be applied) due to non-availability of data (objects) or data being in an inconsistent state.

Let us take simple IPv4 address validator. Here is the code.

public static boolean isValidIPV4Address(String ipAddress)
{  
boolean isIp = false;
StringTokenizer tokens = new StringTokenizer(ipAddress, "."); if(tokens.countTokens() == 4)
{
// logic to validate ip address
// set isIp to true or false;
}
return isIp;
}

The above code is potentially dangerous if null is passed into the method. It crashes and brings everything to grinding halt. We can fix this by just adding a null check (and we have been often told to do that but we hardly follow it). The code will look something like this.


public static boolean isValidIPV4Address(String ipAddress)
{
                if(ipAddress == null)
                    throw new NullPointerException();
boolean isIp = false;
StringTokenizer tokens = new StringTokenizer(ipAddress, "."); if(tokens.countTokens() == 4)
{
// logic to validate ip address
// set isIp to true or false;
}
return isIp;
}

And thats how you fail early. You validate the inputs (irrespective of the number of arguments) and flag/fail early without changing the state if the arguments (inputs) sound weird. If you still operate on the data that is passed and change the state of the system, you add more pain by pushing the system to an inconsistent state. [Read Effective Java by Joshua Bloch if you haven't read it yet and if you want to be told by a Java expert]

If you think above is a good way, hold on. You have better way.

Guava (Google collection library) has a better way to handle this by using Preconditions. Replace the null check with one line statement and bingo Guava helps you to throw the exception.


public static boolean isValidIPV4Address(String ipAddress)
{  
Preconditions.checkNotNull(ipAddress); 
boolean isIp = false;
StringTokenizer tokens = new StringTokenizer(ipAddress, "."); if(tokens.countTokens() == 4)
{
// logic to validate ip address
// set isIp to true or false;
}
return isIp;
}

If "null" is passed, Preconditions.checkNotNull throws NullPointerException. You can also check for the validity of expression using Preconditions.checkArgument (check out Javadoc). Apart from improving the readability of code (to reduce boiler plates from code), it helps you to fail faster without causing any trouble to the state of the system.

Check out Preconditions. Here is the Javadoc of Preconditions. Don't you think that Preconditions is worth adding in our source code :-)

In the next post, we will see how to measure time with Guava's Stopwatch.