Monday, 13 February 2012

JDK 7 Multi Catch Blocks for Exceptions

Multi Catch Blocks for Exceptions



If you are keeping an eye on the new features coming with JDK 7 then probably you could have also heard about multi catch blocks.

They are basically a new way to do things. The purpose of these blocks is to handle multiple exceptions. In pre JDK 7 world, if you wanted to catch two different exceptions but wanted to execute same code in the catch blocks then either you need two catch blocks with repeated code or a finally block.

The problem with finally block is that it gets executed even if no exception occurs which means we need to repeat code in catch blocks for printing stack trace or to re-throw exceptions.

But with JDK 7, if want to catch SQLException and IOException both with same code then I can write:

try{
    try-code
}
catch (SQLException | IOException) {
    catch-code
}

I have tried this new feature of JDK 7 with the release milestone M12. The multi catch feature is a part of project Coin which includes other features being introduced in JDK 7. Following is the code I had written:

package com.example;

public class Test{

    public static void main (String args[]){
        try {
            if (args[0].equals("null")) {
                throw (new NullPointerException());
            } else {
                throw (new ArrayIndexOutOfBoundsException());
            }              
        } catch (NullPointerException | ArrayIndexOutOfBoundsException ex) {
            ex.getMessage();
        }
    }
}

Though I could not compile this code with Eclipse Helios, but I could successfully compile it using command line.

The variable ex is an instance of ArrayIndexOutofBoundsException because it is declared with it. I have written the following program to verify it:

public class Main{
    public static void main(String[] args) {
        System.out.println("hello");
         try {
             if (args[0].equals("null")) {
                 throw (new NullPointerException());
             } else {
                 throw (new ArrayIndexOutOfBoundsException());
             }             
         } catch (NullPointerException | ArrayIndexOutOfBoundsException ex) {
             System.out.println(ex instanceof NullPointerException);
             System.out.println(ex instanceof ArrayIndexOutOfBoundsException);
             ex.printStackTrace();
         }
    }
}

Ran it with the command:
java -classpath c:\com\example Main

And the output is:
hello
false
true
java.lang.ArrayIndexOutOfBoundsException: 0
        at Main.main(Main.java:5)

Monday, 10 October 2011

Equals and Hash Code

The Java super class java.lang.Object has two very important methods defined in it. They are -
  • public boolean equals(Object obj)
  • public int hashCode()
These methods prove very important when user classes are confronted with other Java classes, when objects of such classes are added to collections etc. These two methods have become part of Sun Certified Java Programmer 1.4 exam (SCJP 1.4) objectives. This article intends to provide the necessary information about these two methods that would help the SCJP 1.4 exam aspirants. Moreover, this article hopes to help you understand the mechanism and general contracts of these two methods; irrespective of whether you are interested in taking the SCJP 1.4 exam or not. This article should help you while implementing these two methods in your own classes.

public boolean equals(Object obj)

This method checks if some other object passed to it as an argument is equal to the object on which this method is invoked. The default implementation of this method in Object class simply checks if two object references x and y refer to the same object. i.e. It checks if x == y. This particular comparison is also known as "shallow comparison". However, the classes providing their own implementations of the equals method are supposed to perform a "deep comparison"; by actually comparing the relevant data members. Since Object class has no data members that define its state, it simply performs shallow comparison.

This is what the JDK 1.4 API documentation says about the equals method of Object class-

Indicates whether some other object is "equal to" this one.
    The equals method implements an equivalence relation:
  • It is reflexive: for any reference value x, x.equals(x) should return true.
  • It is symmetric: for any reference values x and y, x.equals(y) should return true if and only if y.equals(x) returns true.
  • It is transitive: for any reference values x, y, and z, if x.equals(y) returns true and y.equals(z) returns true, then x.equals(z) should return true.
  • It is consistent: for any reference values x and y, multiple invocations of x.equals(y) consistently return true or consistently return false, provided no information used in equals comparisons on the object is modified.
  • For any non-null reference value x, x.equals(null) should return false.
The equals method for class Object implements the most discriminating possible equivalence relation on objects; that is, for any reference values x and y, this method returns true if and only if x and y refer to the same object (x==y has the value true).

Note that it is generally necessary to override the hashCode method whenever this method is overridden, so as to maintain the general contract for the hashCode method, which states that equal objects must have equal hash codes.

The contract of the equals method precisely states what it requires. Once you understand it completely, implementation becomes relatively easy, moreover it would be correct. Let's understand what each of this really means.

  1. Reflexive - It simply means that the object must be equal to itself, which it would be at any given instance; unless you intentionally override the equals method to behave otherwise.
  2. Symmetric - It means that if object of one class is equal to another class object, the other class object must be equal to this class object. In other words, one object can not unilaterally decide whether it is equal to another object; two objects, and consequently the classes to which they belong, must bilaterally decide if they are equal or not. They BOTH must agree.
    Hence, it is improper and incorrect to have your own class with equals method that has comparison with an object of java.lang.String class, or with any other built-in Java class for that matter. It is very important to understand this requirement properly, because it is quite likely that a naive implementation ofequals method may violate this requirement which would result in undesired consequences.
  3. Transitive - It means that if the first object is equal to the second object and the second object is equal to the third object; then the first object is equal to the third object. In other words, if two objects agree that they are equal, and follow the symmetry principle, one of them can not decide to have a similar contract with another object of different class. All three must agree and follow symmetry principle for various permutations of these three classes.
    Consider this example - A, B and C are three classes. A and B both implement the equals method in such a way that it provides comparison for objects of class A and class B. Now, if author of class B decides to modify its equals method such that it would also provide equality comparison with class C; he would be violating the transitivity principle. Because, no proper equals comparison mechanism would exist for class A and class C objects.
  4. Consistent - It means that if two objects are equal, they must remain equal as long as they are not modified. Likewise, if they are not equal, they must remain non-equal as long as they are not modified. The modification may take place in any one of them or in both of them.
  5. null comparison - It means that any instantiable class object is not equal to null, hence the equals method must return false if a null is passed to it as an argument. You have to ensure that your implementation of the equals method returns false if a null is passed to it as an argument.
  6. Equals & Hash Code relationship - The last note from the API documentation is very important, it states the relationship requirement between these two methods. It simply means that if two objects are equal, then they must have the same hash code, however the opposite is NOT true. This is discussed in details later in this article.
The details about these two methods are interrelated and how they should be overridden correctly is discussed later in this article.

public int hashCode()

This method returns the hash code value for the object on which this method is invoked. This method returns the hash code value as an integer and is supported for the benefit of hashing based collection classes such as Hashtable, HashMap, HashSet etc. This method must be overridden in every class that overrides the equalsmethod.

This is what the JDK 1.4 API documentation says about the hashCode method of Object class-

Returns a hash code value for the object. This method is supported for the benefit of hashtables such as those provided by java.util.Hashtable.
    The general contract of hashCode is:
  • Whenever it is invoked on the same object more than once during an execution of a Java application, the hashCode method must consistently return the same integer, provided no information used in equals comparisons on the object is modified. This integer need not remain consistent from one execution of an application to another execution of the same application.
  • If two objects are equal according to the equals(Object) method, then calling the hashCode method on each of the two objects must produce the same integer result.
  • It is not required that if two objects are unequal according to the equals(java.lang.Object) method, then calling the hashCode method on each of the two objects must produce distinct integer results. However, the programmer should be aware that producing distinct integer results for unequal objects may improve the performance of hashtables.
As much as is reasonably practical, the hashCode method defined by class Object does return distinct integers for distinct objects. (This is typically implemented by converting the internal address of the object into an integer, but this implementation technique is not required by the JavaTM programming language.)

As compared to the general contract specified by the equals method, the contract specified by the hashCode method is relatively simple and easy to understand. It simply states two important requirements that must be met while implementing the hashCode method. The third point of the contract, in fact is the elaboration of the second point. Let's understand what this contract really means.
  1. Consistency during same execution - Firstly, it states that the hash code returned by the hashCode method must be consistently the same for multiple invocations during the same execution of the application as long as the object is not modified to affect the equals method.
  2. Hash Code & Equals relationship - The second requirement of the contract is the hashCode counterpart of the requirement specified by the equalsmethod. It simply emphasizes the same relationship - equal objects must produce the same hash code. However, the third point elaborates that unequal objectsneed not produce distinct hash codes.
After reviewing the general contracts of these two methods, it is clear that the relationship between these two methods can be summed up in the following statement -

Equal objects must produce the same hash code as long as they are equal, however unequal objects need not produce distinct hash codes.

The rest of the requirements specified in the contracts of these two methods are specific to those methods and are not directly related to the relationship between these two methods. Those specific requirements are discussed earlier. This relationship also enforces that whenever you override the equals method, you must override thehashCode method as well. Failing to comply with this requirement usually results in undetermined, undesired behavior of the class when confronted with Java collection classes or any other Java classes.

Correct Implementation Example

The following code exemplifies how all the requirements of equals and hashCode methods should be fulfilled so that the class behaves correctly and consistently with other Java classes. This class implements the equals method in such a way that it only provides equality comparison for the objects of the same class, similar to built-in Java classes like String and other wrapper classes.

1.	public class Test
2.	{
3.		private int num;
4.		private String data;
5.
6.		public boolean equals(Object obj)
7.		{
8.			if(this == obj)
9.				return true;
10.			if((obj == null) || (obj.getClass() != this.getClass()))
11.				return false;
12.			// object must be Test at this point
13.			Test test = (Test)obj;
14.			return num == test.num &&
15.			(data == test.data || (data != null && data.equals(test.data)));
16.		}
17.
18.		public int hashCode()
19.		{
20.			int hash = 7;
21.			hash = 31 * hash + num;
22.			hash = 31 * hash + (null == data ? 0 : data.hashCode());
23.			return hash;
24.		}
25.
26.		// other methods
27.	}

Now, let's examine why this implementation is the correct implementation. The class Test has two member variables - num and data. These two variables define state of the object and they also participate in the equals comparison for the objects of this class. Hence, they should also be involved in calculating the hash codes of this class objects.

Consider the equals method first. We can see that at line 8, the passed object reference is compared with this object itself, this approach usually saves time if both the object references are referring to the same object on the heap and if the equals comparison is expensive. Next, the if condition at line 10 first checks if the argument is null, if not, then (due to the short-circuit nature of the OR || operator) it checks if the argument is of type Test by comparing the classes of the argument and this object. This is done by invoking the getClass() method on both the references. If either of these conditions fails, then false is returned. This is done by the following code -
if((obj == null) || (obj.getClass() != this.getClass())) return false; // prefer
This conditional check should be preferred instead of the conditional check given by -
if(!(obj instanceof Test)) return false; // avoid
This is because, the first condition (code in blue) ensures that it will return false if the argument is a subclass of the class Test. However, in case of the second condition (code in red) it fails. The instanceof operator condition fails to return false if the argument is a subclass of the class Test. Thus, it might violate the symmetry requirement of the contract. The instanceof check is correct only if the class is final, so that no subclass would exist. The first condition will work for both, final and non-final classes. Note that, both these conditions will return false if the argument is null. The instanceof operator returns false if the left hand side (LHS) operand is null, irrespective of the operand on the right hand side (RHS) as specified by JLS 15.20.2. However, the first condition should be preferred for better type checking.

This class implements the equals method in such a way that it provides equals comparison only for the objects of the same class. Note that, this is not mandatory. But, if a class decides to provide equals comparison for other class objects, then the other class (or classes) must also agree to provide the same for this class so as to fulfill the symmetry and reflexivity requirements of the contract. This particular equals method implementation does not violate both these requirements. The lines 14 and 15 actually perform the equality comparison for the data members, and return true if they are equal. Line 15 also ensures that invoking the equals method on String variable data will not result in a NullPointerException.
While implementing the equals method, primitives can be compared directly with an equality operator (==) after performing any necessary conversions (Such as float to Float.floatToIntBits or double to Double.doubleToLongBits). Whereas, object references can be compared by invoking their equals method recursively. You also need to ensure that invoking the equals method on these object references does not result in a NullPointerException.

Here are some useful guidelines for implementing the equals method correctly.
  1. Use the equality == operator to check if the argument is the reference to this object, if yes. return true. This saves time when actual comparison is costly.
  2. Use the following condition to check that the argument is not null and it is of the correct type, if not then return false.
    if((obj == null) || (obj.getClass() != this.getClass())) return false;
    Note that, correct type does not mean the same type or class as shown in the example above. It could be any class or interface that one or more classes agree to implement for providing the comparison.
  3. Cast the method argument to the correct type. Again, the correct type may not be the same class. Also, since this step is done after the above type-check condition, it will not result in a ClassCastException.
  4. Compare significant variables of both, the argument object and this object and check if they are equal. If *all* of them are equal then return true, otherwise return false. Again, as mentioned earlier, while comparing these class members/variables; primitive variables can be compared directly with an equality operator (==) after performing any necessary conversions (Such as float to Float.floatToIntBits or double to Double.doubleToLongBits). Whereas, object references can be compared by invoking their equals method recursively. You also need to ensure that invoking equals method on these object references does not result in a NullPointerException, as shown in the example above (Line 15).
    It is neither necessary, nor advisable to include those class members in this comparison which can be calculated from other variables, hence the word "significant variables". This certainly improves the performance of the equals method. Only you can decide which class members are significant and which are not.
  5. Do not change the type of the argument of the equals method. It takes a java.lang.Object as an argument, do not use your own class instead. If you do that, you will not be overriding the equals method, but you will be overloading it instead; which would cause problems. It is a very common mistake, and since it does not result in a compile time error, it becomes quite difficult to figure out why the code is not working properly.
  6. Review your equals method to verify that it fulfills all the requirements stated by the general contract of the equals method.
  7. Lastly, do not forget to override the hashCode method whenever you override the equals method, that's unpardonable. ;)
Now, let's examine the hashCode method of this example. At line 20, a non-zero constant value 7 (arbitrary) is assigned to an int variable hash. Since the class members/variables num and data do participate in the equals method comparison, they should also be involved in the calculation of the hash code. Though, this is not mandatory. You can use subset of the variables that participate in the equals method comparison to improve performance of the hashCode method. Performance of the hashCode method indeed is very important. But, you have to be very careful while selecting the subset. The subset should include those variables which are most likely to have the greatest diversity of the values. Sometimes, using all the variables that participate in the equals method comparison for calculating the hash code makes more sense.
This class uses both the variables for computing the hash code. Lines 21 and 22 calculate the hash code values based on these two variables. Line 22 also ensures that invoking hashCode method on the variable data does not result in a NullPointerException if data is null. This implementation ensures that the general contract of the hashCode method is not violated. This implementation will return consistent hash code values for different invocations and will also ensure that equal objects will have equal hash codes.
While implementing the hashCode method, primitives can be used directly in the calculation of the hash code value after performing any necessary conversions, such as float to Float.floatToIntBits or double to Double.doubleToLongBits. Since return type of the hashCode method is int, long values must to be converted to the integer values. As for hash codes of the object references, they should be calculated by invoking their hashCode method recursively. You also need to ensure that invoking the hashCode method on these object references does not result in a NullPointerException.

Writing a very good implementation of the hashCode method which calculates hash code values such that the distribution is uniform is not a trivial task and may require inputs from mathematicians and theoretical computer scientist. Nevertheless, it is possible to write a decent and correct implementation by following few simple rules.

Here are some useful guidelines for implementing the hashCode method correctly.
  1. Store an arbitrary non-zero constant integer value (say 7) in an int variable, called hash.
  2. Involve significant variables of your object in the calculation of the hash code, all the variables that are part of equals comparison should be considered for this. Compute an individual hash code int var_code for each variable var as follows -
    1. If the variable(var) is byte, char, short or int, then var_code = (int)var;
    2. If the variable(var) is long, then var_code = (int)(var ^ (var >>> 32));
    3. If the variable(var) is float, then var_code = Float.floatToIntBits(var);
    4. If the variable(var) is double, then -
      long bits = Double.doubleToLongBits(var);
      var_code = (int)(bits ^ (bits >>> 32));
    5. If the variable(var) is boolean, then var_code = var ? 1 : 0;
    6. If the variable(var) is an object reference, then check if it is null, if yes then var_code = 0; otherwise invoke the hashCode method recursively on this object reference to get the hash code. This can be simplified and given as -
      var_code = (null == var ? 0 : var.hashCode());
  3. Combine this individual variable hash code var_code in the original hash code hash as follows -
    hash = 31 * hash + var_code;
  4. Follow these steps for all the significant variables and in the end return the resulting integer hash.
  5. Lastly, review your hashCode method and check if it is returning equal hash codes for equal objects. Also, verify that the hash codes returned for the object are consistently the same for multiple invocations during the same execution.
The guidelines provided here for implementing equals and hashCode methods are merely useful as guidelines, these are not absolute laws or rules. Nevertheless, following them while implementing these two methods will certainly give you correct and consistent results.

Summary & Miscellaneous Tips

  • Equal objects must produce the same hash code as long as they are equal, however unequal objects need not produce distinct hash codes.
  • The equals method provides "deep comparison" by checking if two objects are logically equal as opposed to the "shallow comparison" provided by the equality operator ==.
  • However, the equals method in java.lang.Object class only provides "shallow comparison", same as provided by the equality operator ==.
  • The equals method only takes Java objects as an argument, and not primitives; passing primitives will result in a compile time error.
  • Passing objects of different types to the equals method will never result in a compile time error or runtime error.
  • For standard Java wrapper classes and for java.lang.String, if the equals argument type (class) is different from the type of the object on which theequals method is invoked, it will return false.
  • The class java.lang.StringBuffer does not override the equals method, and hence it inherits the implementation from java.lang.Object class.
  • The equals method must not provide equality comparison with any built in Java class, as it would result in the violation of the symmetry requirement stated in the general contract of the equals method.
  • If null is passed as an argument to the equals method, it will return false.
  • Equal hash codes do not imply that the objects are equal.
  • return 1; is a legal implementation of the hashCode method, however it is a very bad implementation. It is legal because it ensures that equal objects will have equal hash codes, it also ensures that the hash code returned will be consistent for multiple invocations during the same execution. Thus, it does not violate the general contract of the hashCode method. It is a bad implementation because it returns same hash code for all the objects. This explanation applies to all implementations of the hashCode method which return same constant integer value for all the objects.
  • In standard JDK 1.4, the wrapper classes java.lang.Short, java.lang.Byte, java.lang.Character and java.lang.Integer simply return the value they represent as the hash code by typecasting it to an int.
  • Since JDK version 1.3, the class java.lang.String caches its hash code, i.e. it calculates the hash code only once and stores it in an instance variable and returns this value whenever the hashCode method is called. It is legal because java.lang.String represents an immutable string.
  • It is incorrect to involve a random number directly while computing the hash code of the class object, as it would not consistently return the same hash code for multiple invocations during the same execution.

How to use Comparator and Comparable in Java? With example

Comparators and comparable in Java are two of fundamental interface of Java API which is very important to understand toimplement sorting in Java. It’s often required to sort objects stored in any collection class or in Array and that time we need to use compare () andcompare To () method defined in java.util.Comparator and java.lang.Comparable class. Let’s see some important points about both Comparable and Comparator in Java before moving ahead



Difference between Comparator and Comparable in Java

1) Comparator in Java is defined in java.util package whileComparable interface in Java is defined in java.lang package.
2) Comparator interface in Java has method public int compare (Object o1, Object o2) which returns a negative integer, zero, or a positive integer as the first argument is less than, equal to, or greater than the second. While Comparable interface has method public int compareTo(Object o) which returns a negative integer, zero, or a positive integer as this object is less than, equal to, or greater than the specified object.
3) If you see then logical difference between these two is Comparator in Java compare two objects provided to him, while Comparable interface compares "this" reference with the object specified.
4) Comparable in Java is used to implement natural ordering of object. In Java API String, Date and wrapper classes implementComparable interface.
5) If any class implement Comparable interface in Java then collection of that object either List or Array can be sorted automatically by using  Collections.sort() or Array.sort() method and object will be sorted based on there natural order defined by CompareTo method.
6)Objects which implement Comparable in Java  can be used as keys in a sorted map or elements in a sorted set for example TreeSet, without specifying any Comparator.



Example of using Comparator and Comparable in Java

compareto,compare to java,compare to in java
So in Summary if you want to sort based on natural order or object then use Comparable in Java and if you want to sort on some other attribute of object then Comparator in Java  is the way to go. Now to understand these concepts lets see an example

1) There is class called Person, sort the Person based on person_id.
2) Sort the Person based on Name.

For a Person class sorting based on person_id can be treated as natural order sorting and sorting based on Name can be implemented using Comparator interface. To sort based on person_id we need to implement compareTo() method.


public class Person implements Comparable {
    private int person_id;
    private String name;
    
    /**
     * Compare current person with specified person
     * return zero if person_id for both person is same 
     * return negative if current person_id is less than specified one
     * return positive if specified person_id is greater than specified one
     */
    public int compareTo(Person o) {
        return this.person_id - o.person_id ;
    }
    ….
}

And for sorting based on person name we can implementcompare (Object o1, Object o2) method of Comparator in Java orJava Comparator class.

public class PersonSortByPerson_ID implements Comparator{

    public int compare(Person o1, Person o2) {
        return o1.getPersonId() - o2.getPersonId();
    }
}

You can write several types of Java Comparator based upon your need for example  reverseComparator , ANDComparator , ORComparator etc which will return negative or positive numberbased upon logical results.


How to Compare String in Java

comparator in java,compare to java,java comparator example
For comparing String in Java we should not be worrying because StringimplementsComparable interface in Java and provides implementation for CompareTo method which Compare two strings based on  characters inside or you can say in lexical order. You just need to call String.compareTo(AnotherString) and Java will determine whether specified String is greater than , equal to or less than current String. String is also immutable in Java an important property to remember.



How to Compare Dates in Java

Dates are represented by java.util.Date class in Java and like String Dates alsoimplementsComparable in Java so they will be automatically sorted based on there natural ordering if they got stored in any sorted collection like TreeSet or TreeMap. If you explicitly wants to compare two dates in Java you can call Date.compareTo(AnotherDate) method in Java and it will tell whether specified date is greater than , equal to or less thancurrent String.


This article is in continuation of my previous articles How Classpath works in Java and How to write Equals method in java  and How to use Arraylist in Java using generics  so if you haven’t read those you may find it interesting.

Difference between HashMap and HashTable? Can we make hashmap synchronized?


1. The HashMap class is roughly equivalent to Hashtable, except that it is non synchronized and permits nulls. (HashMap allows null values as key and value whereas Hashtable doesn't allow nulls).
2. HashMap does not guarantee that the order of the map will remainconstant over time.
3. HashMap is non synchronized whereas Hashtable is synchronized.
4. Iterator in the HashMap is  fail-fast  while the enumerator for the Hashtable is not and throw ConcurrentModificationException if any other Thread modifies the map structurally  by adding or removing any element except Iterator's own remove()  method. But this is not a guaranteed behavior and will be done by JVM on best effort.

Note on Some Important Terms
1)Synchronized means only one thread can modify a hash table at one point of time. Basically, it means that any thread before performing an update on a hashtable will have to acquire a lock on the object while others will wait for lock to be released.

2)Fail-safe is relevant from the context of iterators. If an iterator has been created on a collection object and some other thread tries to modify the collection object "structurally", a concurrent modificationexception wjavascript:void(0)ill be thrown. It is possible for other threads though to invoke "set" method since it doesn't modify the collection "structurally". However, if prior to calling "set", the collection has been modified structurally, "IllegalArgumentException" will be thrown.

3)Structurally modification means deleting or inserting element which could effectively change the structure of map.

HashMap can be synchronized by

Map m = Collections.synchronizeMap(hashMap);

Monday, 3 October 2011

JDK 7: The New Objects Class


It was announced approximately 18 months ago that JDK 7 would include a new java.util.Objects classthat would "hold commonly-written utility methods." As part of this announcementJoe Darcy asked the community, "What other utility methods would have broad enough use and applicability to go into a common java.util class?" There were forums and posts on the matter and I blogged about this forthcoming class. The JDK 7 preview release includes this class and it can be tried out now. In this post, I look at use of most of the methods provided by this class and look at how NetBeans 6.9 already uses this class in some of its auto-generated methods.

The java.util.Objects class is new to JDK 7 and its Javadoc states that the class is "since 1.7" and describes the class as: "This class consists of static utility methods for operating on objects. These utilities include null-safe or null-tolerant methods for computing the hash code of an object, returning a string for an object, and comparing two objects." There are currently nine static methods with public accessibility: a compare method, a deepEquals method (for comparing arrays for equality), an equalsmethod, a hash code calculation method potentially for multiple objects, a hashCode method for a single object, overloaded requireNonNull methods, and overloaded toString methods.

There are some general themes associated with the methods provided by the new Objects class. The methods tend to increase null safety. In other words, use of these methods is something I'd be happy to add to my list of Java NullPointerException handling techniques. When one desires an instance's hash code or string representation or one wants to compare an instance to another instance, it is typically prudent to first check the object reference for null to avoid a NullPointerException occurring before the hash code, String representation, or comparison can be made. By moving these common operations out of one of the objects being acted upon into this separate Objects class, the external class can check for null rather than forcing the object itself to be checked explicitly every time.

The second major theme relevant to the methods of the new Objects class is that these methods encapsulate functionality that many developers have written on their own or that other non-standard libraries supply. This new Objects class provides a relatively concise, standardized approach to invoking this common functionality. As will be seen in this post, it makes it easy to clean up commonly implemented methods such as overridden toStringequals, and hashCode methods and to enforce non-null parameter contract constraints.

Unlike the ever-present java.lang.Object class, but like fellow classes in the java.util package, the
java.util.Objects class must be explicitly imported in Java classes that make use of it. TheObjects class does NOT need to be explicitly imported when used in Groovy because Groovy automatically imports classes in the java.util package. Because all examples in this post are written in Java, the java.util.Objects class will be explicitly imported in each class.

The next code listing is for a simple 
Person class. I generated this class's hashCode() andequals(Object) methods using NetBeans 6.9's "Insert Code" mechanism and was pleased to see that (assuming I had the Java 1.7 Platform set for my project) the relevant Objects class methods were used in these automatically generated methods. The automatically generated toString() did not make use of either of the overloaded Objects.toString() methods. I assumed that might have been because the Person class has only String attributes and these don't need to be checked for null before the implicit toString() is invoked on them. However, even when I added a more complex data type that would lead to an NPE when its implicit toString() was called, NetBeans did not use theObjects.toString() method to avoid the potential NPE.

Person.java

  1. package dustin.examples;  
  2.   
  3. import java.util.Objects;  
  4.   
  5. /** 
  6.  * Simple class to be used in demonstration of JDK 7's java.util.Objects class. 
  7.  * 
  8.  * @author Dustin 
  9.  */  
  10. public class Person  
  11. {  
  12.    private String lastName;  
  13.   
  14.    private String firstName;  
  15.   
  16.    /** 
  17.     * Parameterized constructor for instantiating a Person. Both a non-null first 
  18.     * name and a non-null last name must be provided (no "Madonna" or "Lindsay" 
  19.     * or "Seal" allowed here [unless you pass one name as an empty String]). 
  20.     * 
  21.     * @param newLastName This Person instance's last name; must not be null. 
  22.     * @param newFirstName This Person instance's first name; must not be null. 
  23.     * @throws NullPointerException Thrown if either provided name parameter is 
  24.     *   null. 
  25.     */  
  26.    public Person(final String newLastName, final String newFirstName)  
  27.    {  
  28.       this.lastName = Objects.requireNonNull(newLastName, "Last name cannot be null.");  
  29.       this.firstName = Objects.requireNonNull(newFirstName, "First name cannot be null.");  
  30.    }  
  31.   
  32.    public String getLastName()  
  33.    {  
  34.       return this.lastName;  
  35.    }  
  36.   
  37.    public String getFirstName()  
  38.    {  
  39.       return this.firstName;  
  40.    }  
  41.   
  42.    /** 
  43.     * NetBeans 6.9-generated equals(Object) method. It used 
  44.     * Objects.equals(Object, Object) to avoid the need to check for null on any 
  45.     * references before comparing them. This can really clean up equals method 
  46.     * implementations. 
  47.     * 
  48.     * @param obj Object to be compared to me for equality. 
  49.     * @return {@code true} if the provided object is considered equal to me; 
  50.     *    {@code false} otherwise. 
  51.     */  
  52.    public boolean equals(Object obj)  
  53.    {  
  54.       if (obj == null)  
  55.       {  
  56.          return false;  
  57.       }  
  58.       if (getClass() != obj.getClass())  
  59.       {  
  60.          return false;  
  61.       }  
  62.       final Person other = (Person) obj;  
  63.       if (!Objects.equals(this.lastName, other.lastName))  
  64.       {  
  65.          return false;  
  66.       }  
  67.       if (!Objects.equals(this.firstName, other.firstName))  
  68.       {  
  69.          return false;  
  70.       }  
  71.       return true;  
  72.    }  
  73.   
  74.    /** 
  75.     * NetBeans 6.9-generated hashCode(). It used Objects.hashCode(Object)! 
  76.     *  
  77.     * @return Hash code for this instance. 
  78.     */  
  79.    public int hashCode()  
  80.    {  
  81.       int hash = 5;  
  82.       hash = 97 * hash + Objects.hashCode(this.lastName);  
  83.       hash = 97 * hash + Objects.hashCode(this.firstName);  
  84.       return hash;  
  85.    }  
  86.   
  87.    @Override  
  88.    public String toString()  
  89.    {  
  90.       return this.firstName + " " + this.lastName;  
  91.    }  
  92. }  

The NetBeans-generated hashCode() method makes use of Objects.hashCode(Object) to get the individual hash codes of each of its constituent attributes. The advantage of doing this is that each attribute does not need to be checked for null before asking for its hash code. The null checking is still implicitly performed (and zero is returned if the object is null), but the code is much cleaner.

The NetBeans-generated equals(Object) method makes use of Objects.equals(Object, Object) to safely compare the current object's attributes to the provided object's attributes. This method is null-safe and returns true if both attributes being compared are null and returns false if either is null without the other being null. If both compared attributes are non-null, then a standard equality check is made. The Objects.equals(Object,Object) method provides consistent null-safe equality checking with much cleaner code than could be done before this.

The Person class listed above is used by the next code listing, which is the main code listing demonstrating the majority of the methods on the new Objects class.

ObjectsClassDemo.java
  1. package dustin.examples;  
  2.   
  3. import java.util.Objects;   // must be explicitly imported  
  4. import java.util.logging.Level;  
  5.   
  6. import java.util.logging.Logger;  
  7.   
  8. /** 
  9.  * Simple demonstration of the new java.util.Objects class coming with JDK 7. 
  10.  */  
  11. public class ObjectsClassDemo  
  12. {  
  13.    private static final Logger LOGGER = Logger.getLogger(ObjectsClassDemo.class.getName());  
  14.   
  15.    /** 
  16.     * Demonstrate usage of Objects.requireNonNull(Object). 
  17.     * 
  18.     * @param shouldNotBeNull String object be passed to Objects.requireNonNull(Object). 
  19.     */  
  20.    private static void demoObjectsClassNullness(final String shouldNotBeNull)  
  21.    {  
  22.       String stringToUse = null;  
  23.       try  
  24.       {  
  25.          stringToUse= Objects.requireNonNull(shouldNotBeNull);  
  26.       }  
  27.       catch (NullPointerException npe)  
  28.       {  
  29.          LOGGER.severe(npe.toString());  
  30.       }  
  31.       LOGGER.log(Level.INFO, "Provided String was: ''{0}''", stringToUse);  
  32.    }  
  33.   
  34.    /** 
  35.     * Demonstrate usage of Objects.requireNonNull(Object,String). This overloaded 
  36.     * version of Objects.requireNonNull is generally preferable because the 
  37.     * second (String) parameter is the "message" portion of the NullPointerException 
  38.     * that is generated. Without this parameter, the message portion is empty. 
  39.     * 
  40.     * @param shouldNotBeNull String object to be passed to 
  41.     *    Objects.requireNonNull(Object,String) where the first (Object) parameter 
  42.     *    is the object that should not be null and the second (String) parameter 
  43.     *    is the message to display if the first parameter is null. 
  44.     */  
  45.    private static void demoObjectsClassNullness(  
  46.       final String shouldNotBeNull,  
  47.       final String messageIfNull)  
  48.    {  
  49.       String stringToUse = null;  
  50.       try  
  51.       {  
  52.          stringToUse = Objects.requireNonNull(shouldNotBeNull, messageIfNull);  
  53.       }  
  54.       catch (NullPointerException npe)  
  55.       {  
  56.          LOGGER.severe(npe.toString());  
  57.       }  
  58.       LOGGER.log(Level.INFO, "Provided String was: ''{0}''", stringToUse);  
  59.    }  
  60.   
  61.    /** 
  62.     * Demonstrate use of Objects.toString(Object) with default message if provided 
  63.     * object is null. 
  64.     * 
  65.     * @param objectToStringify Object to call Objects.toString(Object) on. 
  66.     */  
  67.    private static void demoNullSafeToStringDefault(  
  68.       final Object objectToStringify)  
  69.    {  
  70.       LOGGER.log(Level.INFO, "toString(): {0}", Objects.toString(objectToStringify));  
  71.    }  
  72.   
  73.    /** 
  74.     * Demonstrate use of Objects.toString(Object, String) with customized String 
  75.     * used to "toString()" when the provided object is null. 
  76.     * 
  77.     * @param objectToStringify Object to call Objects.toString(Object) on. 
  78.     * @param toStringIfObjectIsNull String to be shown as result of "toString()" 
  79.     *    on a null reference. 
  80.     */  
  81.    private static void demoNullSafeToStringCustomized(  
  82.       final Object objectToStringify, final String toStringIfObjectIsNull)  
  83.    {  
  84.       LOGGER.log(Level.INFO, "toString(): {0}", Objects.toString(objectToStringify, toStringIfObjectIsNull));  
  85.    }  
  86.   
  87.    /** 
  88.     * Demonstrate Objects.hash(). The Objects.hashCode() method is also 
  89.     * demonstrated and it is handy to be able to safely get a hash code without 
  90.     * explicit null check (0 is returned by Objects.hashCode(Object) if the 
  91.     * provided Object reference is null). It is also important to note that 
  92.     * calling Objects.hash(Object...) on a single object will NOT result in the 
  93.     * same hash code returned from Objects.hashCode(Object) on that same object. 
  94.     * 
  95.     * @param objectsToHash One or more objects to hash. 
  96.     */  
  97.    private static void demoHash(final Object firstObjectToHash, final Object ... objectsToHash)  
  98.    {  
  99.       final int numberObjects =  
  100.            objectsToHash.length  
  101.          + (firstObjectToHash != null ? 1 : 0);  
  102.       final int multipleObjectsHash = Objects.hash(objectsToHash);  
  103.       LOGGER.log(Level.INFO, "Hash Code for {0} objects: {1}",  
  104.                  new Object[]{numberObjects, multipleObjectsHash});  
  105.       LOGGER.log(Level.INFO, "Hash code for first object ({0}) of {1} object(s) is: {2}",  
  106.                  new Object[]{Objects.toString(firstObjectToHash), numberObjects, Objects.hashCode(firstObjectToHash)});  
  107.    }  
  108.   
  109.    /** 
  110.     * Demonstrate Objects.equals(Object, Object) method. 
  111.     * 
  112.     * @param firstObject First object to be compared by Objects.equals(Object,Object). 
  113.     * @param secondObject Second object to be compared by Objects.equals(Object,Object). 
  114.     */  
  115.    private static void demoEquals(final Object firstObject, final Object secondObject)  
  116.    {  
  117.       final String aproposPhrase =  Objects.equals(firstObject, secondObject)  
  118.                                   ? " is equal to "  
  119.                                   : " is NOT equal to ";  
  120.       LOGGER.log(Level.INFO, "{0}{1}{2}",  
  121.                  new Object[]{Objects.toString(firstObject), aproposPhrase, Objects.toString(secondObject)});  
  122.    }  
  123.   
  124.    /** 
  125.     * Main demonstration executable. 
  126.     * 
  127.     * @param arguments Command-line arguments; none anticipated. 
  128.     */  
  129.    public static void main(final String[] arguments)  
  130.    {  
  131.       demoObjectsClassNullness("Dustin");  
  132.       demoObjectsClassNullness(null);  
  133.   
  134.       demoObjectsClassNullness("Dustin""The String you passed is null!");  
  135.       demoObjectsClassNullness(null"The String you passed is null!");  
  136.   
  137.       final Person person = new Person("Smith""William");  
  138.       Person nullPerson = null;  
  139.       try  
  140.       {  
  141.          nullPerson = new Person("Dump"null);  
  142.       }  
  143.       catch (NullPointerException npe)  
  144.       {  
  145.          LOGGER.severe(npe.toString());  
  146.       }  
  147.   
  148.       demoNullSafeToStringDefault(person);  
  149.       demoNullSafeToStringDefault(nullPerson);  
  150.   
  151.       demoNullSafeToStringCustomized(person, "No such person");  
  152.       demoNullSafeToStringCustomized(nullPerson, "No such person");  
  153.   
  154.       demoHash(person, "Dustin");  
  155.       demoHash("Dustin", person);  
  156.       demoHash(person);  
  157.       demoHash("Dustin");  
  158.       demoHash(nullPerson);  
  159.   
  160.       final Person person2 = new Person("Smith""Barney");  
  161.       final Person person3 = new Person("Smith""Barney");  
  162.       demoEquals(person, person2);  
  163.       demoEquals(person, nullPerson);  
  164.       demoEquals(person2, person3);  
  165.       demoEquals(nullPerson, null);  
  166.    }  
  167. }  

The ObjectsClassDemo class contained in the code listing above demonstrates most of the methods on the Objects class. The output from running the above class's main function is shown next.

Mar 26, 2011 11:35:26 PM dustin.examples.ObjectsClassDemo demoObjectsClassNullness
INFO: Provided String was: 'Dustin'
Mar 26, 2011 11:35:26 PM dustin.examples.ObjectsClassDemo demoObjectsClassNullness
SEVERE: java.lang.NullPointerException
Mar 26, 2011 11:35:26 PM dustin.examples.ObjectsClassDemo demoObjectsClassNullness
INFO: Provided String was: 'null'
Mar 26, 2011 11:35:26 PM dustin.examples.ObjectsClassDemo demoObjectsClassNullness
INFO: Provided String was: 'Dustin'
Mar 26, 2011 11:35:26 PM dustin.examples.ObjectsClassDemo demoObjectsClassNullness
SEVERE: java.lang.NullPointerException: The String you passed is null!
Mar 26, 2011 11:35:26 PM dustin.examples.ObjectsClassDemo demoObjectsClassNullness
INFO: Provided String was: 'null'
Mar 26, 2011 11:35:26 PM dustin.examples.ObjectsClassDemo main
SEVERE: java.lang.NullPointerException: First name cannot be null.
Mar 26, 2011 11:35:26 PM dustin.examples.ObjectsClassDemo demoNullSafeToStringDefault
INFO: toString(): William Smith
Mar 26, 2011 11:35:26 PM dustin.examples.ObjectsClassDemo demoNullSafeToStringDefault
INFO: toString(): null
Mar 26, 2011 11:35:26 PM dustin.examples.ObjectsClassDemo demoNullSafeToStringCustomized
INFO: toString(): William Smith
Mar 26, 2011 11:35:26 PM dustin.examples.ObjectsClassDemo demoNullSafeToStringCustomized
INFO: toString(): No such person

Mar 26, 2011 11:35:26 PM dustin.examples.ObjectsClassDemo demoHash
INFO: Hash Code for 2 objects: 2,058,375,062
Mar 26, 2011 11:35:26 PM dustin.examples.ObjectsClassDemo demoHash
INFO: Hash code for first object (William Smith) of 2 object(s) is: -2,111,928,853
Mar 26, 2011 11:35:26 PM dustin.examples.ObjectsClassDemo demoHash
INFO: Hash Code for 2 objects: -2,111,928,822
Mar 26, 2011 11:35:26 PM dustin.examples.ObjectsClassDemo demoHash
INFO: Hash code for first object (Dustin) of 2 object(s) is: 2,058,375,031
Mar 26, 2011 11:35:26 PM dustin.examples.ObjectsClassDemo demoHash
INFO: Hash Code for 1 objects: 1
Mar 26, 2011 11:35:26 PM dustin.examples.ObjectsClassDemo demoHash
INFO: Hash code for first object (William Smith) of 1 object(s) is: -2,111,928,853
Mar 26, 2011 11:35:26 PM dustin.examples.ObjectsClassDemo demoHash
INFO: Hash Code for 1 objects: 1
Mar 26, 2011 11:35:26 PM dustin.examples.ObjectsClassDemo demoHash
INFO: Hash code for first object (Dustin) of 1 object(s) is: 2,058,375,031
Mar 26, 2011 11:35:26 PM dustin.examples.ObjectsClassDemo demoHash
INFO: Hash Code for 0 objects: 1
Mar 26, 2011 11:35:26 PM dustin.examples.ObjectsClassDemo demoHash
INFO: Hash code for first object (null) of 0 object(s) is: 0

Mar 26, 2011 11:35:26 PM dustin.examples.ObjectsClassDemo demoEquals
INFO: William Smith is NOT equal to Barney Smith
Mar 26, 2011 11:35:26 PM dustin.examples.ObjectsClassDemo demoEquals
INFO: William Smith is NOT equal to null
Mar 26, 2011 11:35:26 PM dustin.examples.ObjectsClassDemo demoEquals
INFO: Barney Smith is equal to Barney Smith
Mar 26, 2011 11:35:26 PM dustin.examples.ObjectsClassDemo demoEquals
INFO: null is equal to null

The above code and its corresponding output lead to several observations:
  • The overloaded Objects.requireNonNull methods are useful for easily checking parameters to ensure that they are not null and throwing a NullPointerException if any is null.
    • The Objects.requireNonNull(T) method that only accepts a single parameter throws a NullPointerException without a message portion while theObjects.requireNonNull(T, String) method provides the String (second) parameter as the message portion of the NullPointerException. I prefer the latter because one of my personal pet peeves is exception's without a message String.
  • The overloaded Objects.toString(Object) methods are similar to the requireNonNullmethods in that uses a "default" while the other allows a customized String to be provided. Both of these methods ensure that a String representation of some sort is provided, even for null references.
  • The Objects.hash(Object...) method and the Objects.hashCode(Object) methods provide null-safe functionality for accessing hash codes.
    • The Objects.hash(Object...) method provides a hash code constructed from multiple objects. Note that this method does NOT return the same hash code for a single provided object as would be returned for the same single object is passed to Objects.hashCode(Object).
    • The Objects.hashCode(Object) method is for acquiring a hash code for a single object in a null-safe way. A zero is returned by this method if the provided object is null.
  • Objects.equals(Object,Object) provides a null-safe way to check two objects for equality. As described above, it returns true if both arguments are null.

I don't specifically focus on the Objects.deepEquals(Object,Object) method or theObjects.compare(T,T,Comparator) method here. They perform as you'd expect from their names. ThedeepEquals method is used to compare objects that are arrays using Arrays.deepEquals. Thecompare method returns zero if both provided objects comparison would normally equal zero or if both provided references are null.

Other References

Additional coverage of the java.util.Objects class can be found in Java 7: The New java.util.Objects ClassThe Java 7 Features Bound to Make Developers More Productive, and JDK 7: What Frequently Rewritten Methods Should be Included in java.util.Objects?

Conclusion

The java.util.Objects class will provide Java developers with a concise, standardized approach for performing tasks that they've previously had to use non-standard and/or verbose custom code to resolve. Even when developers use IDEs to generate their code, the benefit of more concise and readable code remains. As shown in this blog post, NetBeans 6.9 is already capable of generating code that makes use of the Objects class.