You might have seen both getClass(), and instanceof operator in Java can be used in the equals() method to verify the type of the object you are checking for equality. Do you know what the difference is between using getClass() vs instanceof operator in Java? What would be the consequence of using one over the other in the equals() method? This is one of the tricky Java interview questions, which some of you might have encountered. There is a very subtle difference between getClass() and instanceof operator, which can cause potential issues with respect to the equals() method.
Coming to the point, the key difference between them is that getClass() only returns true if the object is actually an instance of the specified class but an instanceof operator can return true even if the object is a subclass of a specified class or interface in Java.
So, you can see that getClass() put a restriction that objects are only equal to other objects of the same class, the same runtime type, but instanceof operator returns true for subclass as well.
If you use the getClass() in the equals() method then it will only return true if the other object is also of the same class or same runtime type, it will return false even if its object of subclass and follow the Liskov substitution principle.
The instanceof operator lets you implement equality between super class and sub class. This is very important from the Collections framework perspective which uses the equals() method to find values. If you use the instanceof operator in equals() method then you can retrieve values even with the object of the subclass as a key provided they have the same content, but this is not possible when you use the getClass() method.
Hibernate relies for its performance gain on this behavior of instanceof operator. If you remember, there is a restriction in place for any Entity or Persistence class in Hibernate that it cannot be final.
This can break the symmetry clause of the equals() method but can also be leveraged for flexibility and performance as Hibernate does by using proxies in place of actual classes. Let's see some code examples to understand this difference better.
Difference between instanceof vs getClass() in Java
Before jumping into the equals() method and how they break the symmetry clause let's verify the behavior getClass() and instanceof operator in Java. Consider the below code, what do you think it will return, true or false?boolean result = (loader.getClass() == Thread.class); // true
result = (loader.getClass() == Runnable.class);
// false because we are testing against Runnable
result = loader instanceof Thread;
// true because the loader is an object of Thread class
result = loader instanceof Runnable;
// true because the loader is an instance of Thread
// and it implements Runnable
So, you can see that getClass() put a restriction that objects are only equal to other objects of the same class, the same runtime type, but instanceof operator returns true for subclass as well.
If you use the getClass() in the equals() method then it will only return true if the other object is also of the same class or same runtime type, it will return false even if its object of subclass and follow the Liskov substitution principle.
Due to this restriction, many Java developers including the great Joshua Bloch have recommended using the instanceof operator in equals() method.
The instanceof operator lets you implement equality between super class and sub class. This is very important from the Collections framework perspective which uses the equals() method to find values. If you use the instanceof operator in equals() method then you can retrieve values even with the object of the subclass as a key provided they have the same content, but this is not possible when you use the getClass() method.
Hibernate relies for its performance gain on this behavior of instanceof operator. If you remember, there is a restriction in place for any Entity or Persistence class in Hibernate that it cannot be final.
This is because hibernate internally creates Proxy classes by extending your Entity class and use it until you really need an attribute from the database. Since instanceof is used to verify the type of object, a Proxy can be equal to the original object.
On the other hand, using instanceof operator has one disadvantage as well. It doesn't respect the symmetry contract of equals() method. The symmetry property says that if x.equals(y) is true then y.equals(x) should also be true, but if you swap x with subclass then x instanceof y would be true but y instanceof x will be false, hence equals() method will return false.
On the other hand, using instanceof operator has one disadvantage as well. It doesn't respect the symmetry contract of equals() method. The symmetry property says that if x.equals(y) is true then y.equals(x) should also be true, but if you swap x with subclass then x instanceof y would be true but y instanceof x will be false, hence equals() method will return false.
This is the fact you should consider when deciding whether to use getClass() or instanceof operator for overriding equals() in Java.
That's all on the difference between getClass() and instanceof in Java. Just remember that getClass() return false if you compare it with the instanceof the subclass but the instance of operator trues if the object is a subclass of the class on the right-hand side of the operator.
That's all on the difference between getClass() and instanceof in Java. Just remember that getClass() return false if you compare it with the instanceof the subclass but the instance of operator trues if the object is a subclass of the class on the right-hand side of the operator.
The biggest disadvantage of using getClass() in the equals() method is the fact that you get two objects that appear to be equal (because they are equal on all the fields) but they are not equal because they are of different classes.
This can cause surprising behavior hence Joshua Bloch and others recommend using the instanceof operator inside equals() method in Java.
Other Java articles and Interview questions from Java 67
- 10 equals and hashcode interview questions
- 21 String Programming and Coding Interview Questions
- How to print Fibonacci series in Java using recursion
- What is the difference between StringBuffer and String in Java
- Difference between TreeSet and TreeMap in Java
- Difference between HashMap and ConcurrentHashMap in Java
- Hashtable vs HashMap in Java
No comments:
Post a Comment
Feel free to comment, ask questions if you have any doubt.