How do you check the runtime type of an object in Java, and how do you use the result safely?
There are two main tools. The instanceof operator tests whether an object is an instance of a type, including its subtypes, and it is the one you normally want. The getClass method returns the object's runtime class object, from which you can read the simple name or compare class references with the equality operator.
public class Main {
public static void main(String[] args) {
Object o = "hello";
System.out.println(o.getClass().getSimpleName());
System.out.println(o instanceof String);
System.out.println(o instanceof Integer);
if (o instanceof String) {
String s = (String) o;
System.out.println(s.length());
}
}
}The output shows the difference between the two questions you can ask. The class name tells you precisely what the object is: String. The instanceof checks tell you what it is compatible with: true for String and false for Integer, because a string is not a number.
The narrowing cast after the check is safe because the instanceof test proved it. The compiler understands that inside the branch the reference really is a string, so the cast cannot fail. Without the check, the same cast would be a risk that surfaces at run time as a class cast exception.
There is a third way, and it is the one to avoid: reading the class name as a string and comparing it. That breaks the moment someone subclasses the type you were matching, because the name is different even though the behaviour is compatible. Comparing class references is better than comparing names, and instanceof is better still.