The instanceof operator in Java is used to check if an object belongs to a particular type or not at runtime. It's also a built-in keyword in Java programming language and is mostly used to avoid ClassCastException in Java. It is used as a safety check before casting any object into a certain type. This operator has a form of object instanceof Type and returns true if the object satisfies IS-A relationship with the Type i.e. object is an instance of class Type or object is the instance of a class which extends Type or object is an instance of a class which implements interface Type.
Once an object passed the instanceof check, it's safe to type-cast into that type, without worrying of java.lang.ClassCastException.
By the way, instanceof operator is also a rather lesser-used operator in Java, similar to transient and volatile, and many programmers don't even know the basics of this operator. If you are one of those then you must read this article and bookmark it for future reference.
And, if you are serious about improving your Hibernate and JPA skills then I also recommend you check out Master Hibernate and JPA with Spring Boot in 100 Steps course by Ranga Rao Karnam on Udemy. It's a great course to learn Hibernate and JPA with Spring Boot in a hands-on and practical manner.
Since Hibernate proxies everything, it's not possible to use the getClass() method for type checking, you need to rely on the instanceof operator for that. You can also expect a few questions from the instanceof operator in the OCPJP exam or any core Java interview.
1) instanceof operator will return false if the object is null. For example in the following code, control will not go inside if() block if the object's value is null.
You can use this property of the instanceof operator while overriding the equals() method in Java.
2) The instanceof operator is primarily used to check whether an object is of a certain type or not. In fact, the instanceof operator provides a way to perform runtime type identification in Java, which is unlike C++, not supported by Java. Alternatively, you can also use the getClass() method from java.lang.Class for the same purpose. See the article 2 ways of runtime type identification in Java for more details.
3) One of the most prominent uses of the instanceof operator is to implement the equals() method for Hibernate persistent class. Since Hibernate uses a proxy object, it's not safe to do a type check in equals() method using the getClass() method, as it will never succeed.
Once an object passed the instanceof check, it's safe to type-cast into that type, without worrying of java.lang.ClassCastException.
By the way, instanceof operator is also a rather lesser-used operator in Java, similar to transient and volatile, and many programmers don't even know the basics of this operator. If you are one of those then you must read this article and bookmark it for future reference.
And, if you are serious about improving your Hibernate and JPA skills then I also recommend you check out Master Hibernate and JPA with Spring Boot in 100 Steps course by Ranga Rao Karnam on Udemy. It's a great course to learn Hibernate and JPA with Spring Boot in a hands-on and practical manner.
10 things about instanceof operators in Java
Good knowledge of instanceof operator is essential for Java developers, but It's, even more, important for those JEE developers, who are working in Hibernate, as instanceof has a big role to play in overriding equals() and hashCode() of Hibernate persistent class.Since Hibernate proxies everything, it's not possible to use the getClass() method for type checking, you need to rely on the instanceof operator for that. You can also expect a few questions from the instanceof operator in the OCPJP exam or any core Java interview.
1) instanceof operator will return false if the object is null. For example in the following code, control will not go inside if() block if the object's value is null.
if(object instanceof Order){ Order ord = (Order) object; }
You can use this property of the instanceof operator while overriding the equals() method in Java.
2) The instanceof operator is primarily used to check whether an object is of a certain type or not. In fact, the instanceof operator provides a way to perform runtime type identification in Java, which is unlike C++, not supported by Java. Alternatively, you can also use the getClass() method from java.lang.Class for the same purpose. See the article 2 ways of runtime type identification in Java for more details.
3) One of the most prominent uses of the instanceof operator is to implement the equals() method for Hibernate persistent class. Since Hibernate uses a proxy object, it's not safe to do a type check in equals() method using the getClass() method, as it will never succeed.
Other ways to doing type check e.g. Hibernate.getClass() method will make your entity class dependent on a third-party library and if you want to share your persistent class then you also need to include Hibernate, which is not good at all. That's the reason, I prefer the instanceof operator for doing type checking in the equals() method of Entity class, as shown below:
Since the instanceof operator in Java returns true for the instance of a subclass, this code will work fine with Hibernate proxy classes, which inherit from the persistent class. By the way, instanceof check also breaks equals() method's symmetrical contract, according to that if a.equals(b) is true then b.equals(a) should also be true, but with the instanceof operator in use, if a representative instance of the parent class and b being an instance of the child class, a.equals(b) will return true but b.equals(a) will return false, thus breaking equals() contract of symmetry. Though it's not a real issue until you are doing such comparison e.g. in the Hibernate persistent class.
@Override public boolean equals(Object object) { // instanceof also takes care of null check if (!(object instanceof Customer)) { return false; } Customer other = (Customer) object; // rest of code omitted for brevity }
Since the instanceof operator in Java returns true for the instance of a subclass, this code will work fine with Hibernate proxy classes, which inherit from the persistent class. By the way, instanceof check also breaks equals() method's symmetrical contract, according to that if a.equals(b) is true then b.equals(a) should also be true, but with the instanceof operator in use, if a representative instance of the parent class and b being an instance of the child class, a.equals(b) will return true but b.equals(a) will return false, thus breaking equals() contract of symmetry. Though it's not a real issue until you are doing such comparison e.g. in the Hibernate persistent class.
Java instanceof Example
Here is a sample Java Program to demonstrate the capability of instanceof operators in Java. First, we have created a couple of classes and interfaces to define type hierarchy. We have a class called ObjectOriented and an interface JVMLanguage.Then we have another class called Java which extends ObjectOriented and implements JVMLanguage and another class called CPlusPlus which only extends the ObjectOriented class.
Now with this setup, we will test the instanceof operator to determine whether an object is an instance of any of these classes or not.
You can also run this program by uncommenting certain code which fails instanceof check and subsequent cast will throw java.lang.ClassCastException. This program is self-explanatory, but you should pay attention when instanceof returns false, you can clearly see that it returns true only when we have an IS-A relationship satisfied between A and B in check of A instanceof B. If A is null or there is no IS-A relationship, it will return false and any attempt to cast B into A will throw ClassCastException.
That’s all about what is the instanceof operator in Java and how to use the instanceof operator. In defensive programming, an instanceof check is a must before casting any unknown object. By default don't use the instanceof operator for type checking in equals(), as it breaks the symmetry contract, but remember to use it while overriding equals() for Hibernate persistent class.
Other Hibernate Articles and Interview Questions you may like
class ObjectOriented { } class Java extends ObjectOriented implements JVMLanguage { } class CPlusPlus extends ObjectOriented { } interface JVMLanguage { } import java.io.File; import java.io.IOException; import java.util.Scanner; /** * * @author Javin Paul * */ public class InstanceOfDemo { public static void main(String[] args) { ObjectOriented oops = new ObjectOriented(); Java java = new Java(); CPlusPlus cpp = new CPlusPlus(); // true - because oops is direct instance of ObjectOriented class System.out.println("oops instanceof ObjectOriented : " + (oops instanceof ObjectOriented)); // true - because java is instance of Java class, which is sub-class or ObjectOriented System.out.println("java instanceof ObjectOriented : " + (java instanceof ObjectOriented)); // true - because java is object of Java class, which implements JVMLanguage interface System.out.println("java instanceof JVMLanguage : " + (java instanceof JVMLanguage)); // true - because cpp is object of CPlusPlus, which extends ObjectOriented System.out.println("cpp instanceof ObjectOriented : " + (cpp instanceof ObjectOriented)); // true - because cpp is object of type CPlusPlus System.out.println("cpp instanceof CPlusPlus: " + (cpp instanceof CPlusPlus)); // false - because oops is instance of ObjectOriented, neither extends Java class, nor implement Java interface System.out.println("oops instanceof Java : " + (oops instanceof Java)); //Java fromOops = (Java) oops; // compile ok //- classCastException at runtime // false - because ObjectOriented class does not implement JVMLanguage interface System.out.println("oops instanceof JVMLanguage : " + (oops instanceof JVMLanguage)); //JVMLanguage jvm = (JVMLanguage) oops; // compile fine // - java.lang.ClassCastException at runtime // false - because CPlusPlus class does not implement JVMLanguage interface System.out.println("cpp instanceof JVMLanguage : " + (cpp instanceof JVMLanguage)); // instanceof operator returns false if compared to null java = null; System.out.println("(java =null) instanceof ObjectOriented : " + (java instanceof ObjectOriented)); System.out.println("(java =null) instanceof Java : " + (java instanceof Java)); } } Output: oops instanceof ObjectOriented : true java instanceof ObjectOriented : true java instanceof JVMLanguage : true cpp instanceof ObjectOriented : true cpp instanceof CPlusPlus: true oops instanceof Java : false oops instanceof JVMLanguage : false cpp instanceof JVMLanguage : false (java =null) instanceof ObjectOriented : false (java =null) instanceof Java : false
You can also run this program by uncommenting certain code which fails instanceof check and subsequent cast will throw java.lang.ClassCastException. This program is self-explanatory, but you should pay attention when instanceof returns false, you can clearly see that it returns true only when we have an IS-A relationship satisfied between A and B in check of A instanceof B. If A is null or there is no IS-A relationship, it will return false and any attempt to cast B into A will throw ClassCastException.
That’s all about what is the instanceof operator in Java and how to use the instanceof operator. In defensive programming, an instanceof check is a must before casting any unknown object. By default don't use the instanceof operator for type checking in equals(), as it breaks the symmetry contract, but remember to use it while overriding equals() for Hibernate persistent class.
Other Hibernate Articles and Interview Questions you may like
- Difference between First and Second level cache in Hibernate? (answer)
- Difference between get() and load() method in Hibernate? (answer)
- 5 Spring and Hibernate Training Courses for Java developers (list)
- 2 Books to Learn Hibernate for Beginners (books)
- 5 Books to Learn Spring Framework for Beginners (books)
- Why Hibernate Entity class should not be final in Java? (answer)
- 10 Hibernate Questions from Java Interviews (list)
Nice post but I think the first code has a little error
ReplyDeletewhere is read
if(object instanceof Order){ Order ord = (Order) order; }
should be
if(object instanceof Order){ Order ord = (Order) object; }
@Walter, that's right, thanks for pointing it out. I have corrected it now.
ReplyDelete