Skip to main content

Favour Direct Class References

Be aware of the drawbacks of using Class.getClass() to obtain a Class reference. Class.class can be used at compile time, whilst getClass() is only available at runtime.

Starting with the definitions of each:

  • .getClass() - returns "The Class object that represents the runtime class of this object."
  • .class - returns "The Class object that represents the entity (class, interface, array class, primitive type, or void) named by the binary name, as specified by the Java Language Specification."

Equality

class Building {
private int doors;
}

class House extends Building {}
House building1 = new Building();

Class runtimeType = building1.getClass();
Class staticType = Building.class;

assertSame(runtimeType, staticType); // false

Additionally getClass() requires a virtual function dispatch to be performed, which can be expensive. Take the example below to highlight a potential pitfall:

Logging

This can be a common (non-fatal) pitfall when logging, as the logger now has to be instantiated as a non-static variable. The following example shows a common scenario:

public class Building {
private static final Logger LOGGER = LoggerFactory.getLogger(getClass());

...
}

The issue here is that each time the Building class is instantiated, a new Logger instance is created, whereas if

private static final Logger LOGGER = LoggerFactory.getLogger(Building.class);

was used, only a single instance would be shared across all instantiations.

Primitive Types

The getClass() method is also unusable for any class that cannot be instantiated (e.g. primitive, interface , abstract, etc.) primitive types, whereas the .class method can still be used.

Class runtimeType = int.getClass();

Conclusion

Only use getClass() when you need to obtain a Class reference at runtime, and not at compile time.