Skip to content

Lesson 02 · Reflection (basics)

Beyond the 1Z0-830 exam

Reflection isn't on the 1Z0-830, but it powers the tools an SDET lives in — test runners, mocking (Mockito), DI, and serializers all inspect and invoke code reflectively. Knowing the basics (and the costs) lets you use those tools well and debug them when they misbehave.

Objectives

After this lesson you will be able to:

  • Obtain a Class object and inspect fields, methods, and constructors.
  • Instantiate and invoke reflectively, including accessibility.
  • Judge when reflection is worth it — and when to avoid it.

Getting a Class object

java
Class<?> c1 = String.class;                 // class literal
Class<?> c2 = "hi".getClass();              // from an instance
Class<?> c3 = Class.forName("java.util.ArrayList");   // by name (throws ClassNotFoundException)
c1.getName();        // "java.lang.String"
c1.getSimpleName();  // "String"

Inspecting members

java
Class<?> c = Account.class;
c.getDeclaredFields();        // all fields declared here (any access)
c.getFields();                // public fields, including inherited
c.getDeclaredMethods();
c.getDeclaredConstructor(String.class);

Gotcha

getDeclaredX returns all members declared by this class (including private) but not inherited ones; getX (no "Declared") returns public members including inherited. Mixing them up is a classic reflection bug.

Instantiating and invoking

java
Constructor<Account> ctor = Account.class.getDeclaredConstructor(String.class);
Account a = ctor.newInstance("alice");      // create an instance

Method m = Account.class.getDeclaredMethod("balance");
Object result = m.invoke(a);                // call it; result is boxed Object

Field f = Account.class.getDeclaredField("owner");
f.setAccessible(true);                       // bypass private (if module allows)
String owner = (String) f.get(a);

The cost of reflection

Reflection defeats compile-time checks: wrong names/types fail at runtime (NoSuchMethodException, IllegalAccessException), it's slower than direct calls, and setAccessible(true) can throw InaccessibleObjectException if a module doesn't opens the package (Module 10). Use it for frameworks/tooling, not everyday logic.

SDET note

Mockito, JUnit, and Jackson all use reflection — that's why a test class needs a no-arg constructor, why @Test methods can be package-private, and why deep-reflection on JPMS modules needs opens. When a framework "can't access" your class, the fix is usually visibility or an opens directive, not more reflection.

Key Takeaways

  • Get a Class via T.class, obj.getClass(), or Class.forName(name).
  • getDeclaredX = all members of this class (incl. private, excl. inherited); getX = public members incl. inherited.
  • Instantiate with getDeclaredConstructor(...).newInstance(...); invoke with Method.invoke; read fields with Field.get (setAccessible(true) to bypass private).
  • Reflection trades compile-time safety and speed for flexibility — and needs opens for deep reflection on modules. Reserve it for tooling.

Lesson Quiz

Lesson Quiz · Reflection (basics)0 / 4
  1. Difference between getDeclaredMethods() and getMethods()?

    • ANone
    • BgetDeclaredMethods: all methods of this class (incl. private, excl. inherited); getMethods: public incl. inherited
    • CgetMethods includes private
    • DgetDeclaredMethods includes inherited
  2. Which obtains a Class by its fully-qualified name?

    • AString.class
    • Bobj.getClass()
    • CClass.forName("...")
    • Dnew Class()
  3. What does setAccessible(true) on a module-encapsulated field risk?

    • ANothing
    • BInaccessibleObjectException if the package isn't opened
    • CA compile error
    • DClassCastException
  4. A wrong method name passed to getMethod fails...

    • Aat compile time
    • Bat runtime (NoSuchMethodException)
    • Csilently
    • Dnever

Next: Regular Expressions. Run the matching code in labs/src/main/java/com/jse21/m11_language/.