domingo, abril 10, 2011

Another Shot Of Whiskey Can't Stop Looking At The Door Wishing You'd Come Sweeping In The Way You Did Before (Lady Antebellum - Need You Now)



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:

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.

7 comentarios:

Anónimo dijo...

Nice post. Just a pity that this kind of utility methods were not added before. I guess Apache Commons project had to fill this void.

Victor Herrera dijo...

Very good. Now I now what Objects really does.

I find requireNonNull very useful. I won't need to include an extra library (my own library or open source) to do this.

Ratn Dwivedi dijo...

Would have been better if requireNotNull takes colection of Objects

zartc dijo...

> Would have been better if requireNotNull takes colection of Objects

And a ExceptionType to throw. i.e. Not all argument null check call for a NullPointerException.

Alistair dijo...

Nice. Having used and written all sorts of similar utilities (Spring's ObjectUtils and Assert being my favorite) all these years it's good to finally see these become part of the JDK.

Though, personally, I would've loved to see requireNonNull() implemented as a language feature—ala @NotNull on parameters—that can be statically analyzed and enforced at compile time.

Where else can be give feedback/suggestions on these? Like a var-args version of requireNonNull(), and adding a <T> int compare(Comparable<T>, Comparable<T>) that doesn't require a Comparator. I also have a varargs hashCode() method that basically returns Object#hashCode() if given only a single argument (as opposed to Arrays#hashCode([])) which computes differently.

Anónimo dijo...

Great, but these utilities should be language features, then they would have been really useful. As it is I get the same features plus more from other libraries so not that useful really.

Sverige dijo...

This has got to be one of the best albums I've heard in quite some time. Normally when I purchase an entire album I find I really like some songs, feel ambivilant about a few, and don't care for one or two. This is one of those albums where I like pretty much every song.

Donate If You Can and Find Post Useful