With new release of JDK 7, a lot of really useful features has been developed, some of them I have write off before in this blog (JSR 203 and JSR 166y). In this post I am going to talk about one new small enhancement. This new feature is the addition of java.util.Objects class. This class is similar to java.util.Arrays or java.util.Collections but for objects instead of arrays or collections.
This class offers nine methods grouped by four groups: equality, hashing, nullables, and toString. Let's examine all of them.
- compare(T a, T b, Comparator c):int => Returns 0 if the arguments are identical and c.compare(a, b) otherwise. Consequently, if both arguments are null 0 is returned.
- deepEquals(Object a, Object b):boolean => Returns true if the arguments are deeply equal to each other and false otherwise. Two null values are deeply equal. If both arguments are arrays, the algorithm in Arrays.deepEquals is used to determine equality. Otherwise, equality is determined by using the equals method of the first argument. This operation is useful if you want to compare two objects and you don't know exactly if Object is a "single" object or an array. This method manages this problem, and compares both instances correctly.
- equals(Object a, Object b):boolean => Returns true if the arguments are equal to each other and false otherwise. Consequently, if both arguments are null, true is returned and if exactly one argument is null, false is returned. Otherwise, equality is determined by using the equals method of the first argument. And I suppose you are wondering "nice but I have an equals method in object class". Yes you are right but look next example:
If foo is null, a NullPointerException is thrown. One can argue that you should check for null input parameters, this is a simple example, but I am sure all of us sometimes we have received a NullPointerException in an equals.
But see that:
But see that:
Not And a Half is showed instead of throwing a NullPointerException.
- hash(Object... values):int => Generates a hash code for a sequence of input values. The hash code is generated as if all the input values were placed into an array, and that array were hashed by calling Arrays.hashCode(Object). This method is really useful in DTO objects. For example Hibernate "requires" that all objects implement equals and hashCode. It is typical that DTOs can contain lot of fields, take a look any of these classes how many lines of code can contain those hashCode methods. But see how simple is using this method:
- hashCode(Object o):int => Returns the hash code of a non-null argument and 0 for a null argument.
- requireNonNull(T obj):T => Checks that the specified object reference is not null. This method is designed primarily for doing parameter validation in methods and constructors. If obj variable is null a NullPointerException is thrown. Look next example:
I think it is a clean solution, avoid noise code, and it is more readable than if(foo == null) throw new NullPointerException();
- requireNonNull(T obj, String message): T => Checks that the specified object reference is not null and throws a customized NullPointerException using message parameter, if it is.
- toString(Object o): String => Returns the result of calling toString for a non-null argument and "null" for a null argument.
- toString(Object o, String nullDefault): String => Returns the result of calling toString on the first argument if the first argument is not null and returns the second argument otherwise. I find this method so useful for logging porpoises. Sometimes you are going to log some information that null value has a meaning. For example without using this class, a log line could be:
But would be more readable:
I am sure java.util.Objects would not go down in history as the best new feature added in JDK 7, but honestly, I find it so useful and it will help me so much developing code even more readable. Enjoy it.