Java Reflection API: the Class Object and getClass() - Quiz

Total: 5 questions

1. 

What is the Java Reflection API and what does getClass() return?

Reflection is the ability of a program to inspect itself at runtime: find out which fields, methods and constructors a class has, create an object from a class name, call a method and read or change a field, even a private one. The entry point is java.lang.Class; the classes Field, Method and Constructor live in java.lang.reflect. JUnit, Spring, Hibernate and Jackson are built on reflection.

getClass() is a final method of Object. It returns the Class object that describes the runtime type of the object, not the type of the variable:

Object s = "a string";
System.out.println(s.getClass()); // class java.lang.String

The JVM creates exactly one Class object per loaded type, and Class has no public constructors. Calling getClass() on null throws NullPointerException.

2. 

What is the difference between getClass(), the .class literal and Class.forName()?

All three return the same Class object; they differ in what you start from:

  • obj.getClass() — you have an object and need its runtime type. Throws NullPointerException on null and does not compile for a primitive variable.
  • Name.class — the type is known at compile time; works for primitives and arrays (int.class, int[].class). Does not initialize the class: static blocks do not run.
  • Class.forName("pkg.Name") — the name is known only at runtime (configuration, plugin, JDBC driver). Initializes the class and throws the checked ClassNotFoundException, also for "int". A nested class is written with $: "java.util.Map$Entry", not "java.util.Map.Entry". To load without initialization, use Class.forName(name, false, classLoader).
3. 

Why is Class.newInstance() deprecated and how should you create an object through reflection?

Since Java 9 Class.newInstance() is marked @Deprecated: it propagates checked exceptions of the constructor past the compiler — for example, an IOException thrown by the constructor escapes from a method that does not declare it.

The correct way is to get the constructor and call it:

Class<?> c = Class.forName("HeavyBox");
Object box = c.getDeclaredConstructor().newInstance();

A constructor exception then arrives wrapped in InvocationTargetException (the original one is available through getCause()). For a constructor with parameters, pass the types to getDeclaredConstructor(double.class) and the values to newInstance(12.5).

4. 

How do you access a private field through reflection, and why does setAccessible(true) throw InaccessibleObjectException for JDK classes?

Find the private member with getDeclaredField() / getDeclaredMethod() (getField() and getMethod() see public members only), then open access with setAccessible(true):

Field label = c.getDeclaredField("label");
label.setAccessible(true);
label.set(box, "Fragile");

For your own classes this works without restrictions. Since Java 16–17, however, the packages of the java.base module are closed to deep reflection, so, for example, String.class.getDeclaredField("value").setAccessible(true) throws InaccessibleObjectException. Such a package can be opened only explicitly, with the JVM flag --add-opens.

5. 

Should equals() use getClass() or instanceof?

Both are valid, but they give different semantics, because getClass() compares the exact type while instanceof accepts subclasses:

Box box = new HeavyBox();
System.out.println(box instanceof Box);          // true
System.out.println(box.getClass() == Box.class); // false: the runtime type is HeavyBox

getClass() != o.getClass() treats a subclass object as unequal to a parent object and keeps equals() symmetric under inheritance. instanceof allows comparing with subclasses — convenient when subclasses add no fields used in the comparison, or when the class is declared final.

Page 1 of 1