java.util.Objects- A static utility for objects introduced in Java 7

June 6, 2012

Java 7.0

A lot of you would be unaware of this new static utility for objects introduced in Java 7- its the java.util.Objects class. I came across this usage of class while I was browsing through the updated Java 8 collections API.

The static utility methods added as part of java.util.Objects class allow us to perform null-safe operations on objects. Lets have a look at the use of each of those methods:

compare

This method accepts- the objects to be compared and also a Comparator. If the object references passed are identical, then it returns 0, otherwise it invokes the comparator.compareTo(reference1,reference2). If both the object references are null, it returns 0.
The definition of compare method in java.util.Objects class is:

public static <T> int compare(T a, T b, 
             Comparator<? super T> c) {
    return (a == b) ? 0 :  c.compare(a, b);
}

Lets look at the use of this method:

String s1 = new String("Hello");
String s2 = s1;
int value1 = Objects.compare(s1, s2, 
	new Comparator<String>() {
	@Override
	public int compare(String o1, String o2) {
		return o1.compareTo(o2);
	}
});
//Both s1 and s2 refer to the same object
//Prints 0
System.out.println(value1);
String s3 = new String("Hello2");
int value2 = Objects.compare(s1, s3, 
	new Comparator<String>() {
	@Override
	public int compare(String o1, String o2) {
		return o1.compareTo(o2);
	}
});
/*
 *s1 and s3 refer to different objects, 
 *hence comparator is invoked.
 */
//Prints -1
System.out.println(value2);

deepEquals

This method expects 2 arguments, if both of them are arrays then Arrays.deepEquals is invoked otherwise the equals method on first argument is invoked.

The definition of this method is:

public static boolean deepEquals(Object a, Object b) {
	if (a == b)
		return true;
	else if (a == null || b == null)
		return false;
	else
		return Arrays.deepEquals0(a, b);
}

Lets use Person class for this sample:

class Person{
	String firstName;
	String lastName;
	Person(String fName, String lName){
		firstName = fName;
		lastName = lName;
	}

	@Override
	public boolean equals(Object pObj){
		if ( pObj == null){
			return false;
		}
		Person p = (Person)pObj;
		return (firstName.equals(p.firstName) &&
		lastName.equals(p.lastName));
	}

	@Override
	public String toString(){
		return firstName+" "+lastName;
	}
}

Use of the deepEquals method:

Person p1 = new Person("Mohamed","Sanaulla");
Person p2 = new Person("FirstName","LastName");
Person p3 = new Person("Mohamed","Sanaulla");

//Prints false- p1,p2 have different names.
System.out.println(Objects.deepEquals(p1,p2));

//Prints true- p1,p3 have same names
System.out.println(Objects.deepEquals(p1,p3));

Person[] pArray1 = {p1,p2,p3};
Person[] pArray2 = {p1,p2,p2};
Person[] pArray3 = {p1,p2,p3};
//Prints false- both have last element as different
System.out.println(Objects.deepEquals(pArray1,pArray2));

//Prints true - both have same elements
System.out.println(Objects.deepEquals(pArray1,pArray3));

//Throws exception, as pArray1 cannot be cast to Person
System.out.println(Objects.deepEquals(p1,pArray1));

equals

This method accepts 2 arguments (object references). Returns true if both the references are null, returns false if one of them if null, otherwise invokes the equals method on the first argument.

The definition of equals method in java.util.Objects

public static boolean equals(Object a, Object b) {
	return (a == b) || (a != null && a.equals(b));
}

Sample code which uses the equals method

//Refer to p1,p2,p3 from previous example.
Person p4 = null;
Person p5 = null;
//Prints- true- both are null
System.out.println(Objects.equals(p4,p5));

//Prints- true- both have same names
System.out.println(Objects.equals(p1,p3));

//Prints- false in both the cases below.
System.out.println(Objects.equals(p1,p4));
System.out.println(Objects.equals(p4,p1));

If one of the arguments is null, as expected the method returns false.

hash

This method takes variable number of arguments and calculates the hash on all of the together. This is different from hashCode method as the latter calculates the hash for a single object. This method instead invokes Arrays.hashCode on the arguments passed.
The definition of this method in java.util.Objects

public static int hash(Object... values) {
	return Arrays.hashCode(values);
}

hashCode

Its just a null-safe variant of the Object.hashCode, if the argument passed to this is null it returns 0, otherwise it invokes Object.hashCode. Using this method one can avoid the explicit not null check to be carried out:

if ( p5 != null){
    System.out.println(p5.hashCode());
}
//instead the above can be replaced by
System.out.println(Objects.hashCode(p5));

requireNonNull

This method can be used to verify that the parameters to method and constructors are not null.
The definition of this method in java.util.Objects

public static <T> T requireNonNull(T obj) {
	if (obj == null)
		throw new NullPointerException();
	return obj;
}

The method which uses requireNotNull

private static void checkNotNull(Person p){
	p = Objects.requireNonNull(p);
	System.out.println(p.firstName);
}

and this can be invoked as:

/Prints firstName
checkNotNull(p1);
//As p5=null, throws NPE.
checkNotNull(p5);

There’s another variant of this which accepts a String message and this message is then passed with the NullPointerException.

toString

There’s another variant of this which accepts a default string representation if the argument/reference is null.
The definition of this method is:

public static String toString(Object o) {
	return String.valueOf(o);
}
//Second variant which accepts a default string
public static String toString(Object o,
                              String nullDefault) {
	return (o != null) ? o.toString() : nullDefault;
}

Lets see how this can be used:

//p1,p5 are declared above
//Prints- Mohamed Sanaulla
System.out.println(Objects.toString(p1));

//Prints- null as p5=null
System.out.println(Objects.toString(p5));

//Prints- Null Person, the default string
System.out.println(Objects.toString(p5,"Null Person"));

These static utility methods explained above are a means to avoid explicit null checks on the objects and also provide null safe invocations on various methods like equals, hashCode. I am expecting these would be enhanced further to add more methods. But for now lets make use of these utilities methods. I guess there should be similar APIs provided by Apache Commons, I am not sure though, so please verify if Apache Commons provides similar API.

What do you think about this new static utility?

email

Comments

comments

, ,

About Mohamed Sanaulla

In his day job he works on developing enterprise applications using ADF. He is also the moderator of JavaRanch forums and an avid blogger.

View all posts by Mohamed Sanaulla
  • Bas Leijdekkers

    Your Person.equals() method throws a NullPointerException when the argument is null.

    • http://sanaulla123.googlepages.com Mohamed Sanaulla

      If you are talking about this line:
      System.out.println(Objects.equals(p1,p4));
      then as I mentioned in the code itself, it throws up NullPointerException and it is a bug in the API.
      And there is not such call as Person.equals() because equals is a non-static method.

  • Вячеслав Сахно

    Oracle needed 20 years to start extracting  methods implementation from java.lang.Object. Maybe in 10 more years they’ll decide to inject this implementations and also find that non nullnes can be checked at compile time. Whatever.

  • Pingback: Various API and language enhancements as part of Java 7 | Experiences Unlimited

  • Pingback: JavaPins

  • Pingback: Overriding the toString() method in Object classJavaBeat