Explain Codes LogoExplain Codes Logo

How to determine an object's class?

java
instanceof
class-checks
polymorphism
Nikita BarsukovbyNikita Barsukov·Feb 16, 2025
TLDR

Get an object's class using obj.getClass(). It returns a Class<?> object. Here is an example:

Object obj = "Hello"; System.out.println(obj.getClass().getSimpleName()); // Prints String because obj is a String instance.

To ascertain whether an object is an instance of a specific class, resort to the instanceof operator:

if (obj instanceof String) { System.out.println("Phew! It's a String, not a slinky!"); // Humorous comment, indicating that toString would work without unexpected results }

instanceof returns true or false, based on whether the object is a member of the class (or subclass) you specified.

Performing subclass checks

While dealing with base class objects, you may need to confirm whether they're instances of a specific subclass. Enter instanceof:

if (obj instanceof SubClass) { System.out.println("Eureka! It's SubClass!"); // Another humorous comment, excited that it's the expected class }

A bonus is that instanceof also checks for non-null objects, preventing NullPointerExceptions.

Probing class equality

Class instances can be compared for equality using the == operator:

boolean isEqual = obj.getClass() == String.class; // True if obj is a String, false if it's an armadillo or anything else.

isAssignableFrom() is crucial while assessing class hierarchy:

boolean isAssignable = ParentClass.class.isAssignableFrom(obj.getClass()); // See if obj is a rebellious child or a conforming parent.

Inverse relationship doesn't hold here! Class hierarchy is like a strict parent-child heirarchy, no rebellions allowed!

Compatibility with a particular class

Check if a given object is compatible with a class using:

boolean isInstance = DesiredClass.class.isInstance(obj); // see if we can shape-shift obj into DesiredClass without causing a scene.

Safe casting of objects

And when you want to cast the object but you're cautious:

MyClass castedObj = MyClass.class.cast(obj);

This ensures safe casting – a ClassCastException gets thrown if the object cannot be cast to the specified class.

The role of design in reducing class checks

Good design can reduce the need for explicit class checks. Marvel at the power of polymorphism and design patterns which handle these variations, saving you from constant checking with instanceof and getClass().

Indications of less-than-optimal design:

  • Frequent dependency on instanceof suggests subclass responsibilities may be misplaced.
  • Using getClass() may hint at insufficient abstraction.
  • "Castitis" (inordinate casting) often raises red flags about breaching encapsulation.

Pertinently applying polymorphism and design patterns should help you avoid constant class type checks.

To get class related information during runtime:

Class<?> clazz = obj.getClass(); String className = clazz.getName(); // In case you need to impress a log file somewhere.

Advanced use and potential hazards

Verify interface implementation

Check if an object implements an interface thus:

boolean implementsInterface = anInterface.class.isInstance(obj);

Nullability issues

Beware the NullPointerException! getClass() on a null reference is the java equivalent of a step in the abyss!

Subclass variance

Depending on Class.getName() for type checks can be risky as subclasses will have different names, leading to false negatives in the equality checks.