Appearance
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
Classobject 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
ClassviaT.class,obj.getClass(), orClass.forName(name). getDeclaredX= all members of this class (incl. private, excl. inherited);getX= public members incl. inherited.- Instantiate with
getDeclaredConstructor(...).newInstance(...); invoke withMethod.invoke; read fields withField.get(setAccessible(true)to bypass private). - Reflection trades compile-time safety and speed for flexibility — and needs
opensfor deep reflection on modules. Reserve it for tooling.
Lesson Quiz
Difference between getDeclaredMethods() and getMethods()?
Which obtains a Class by its fully-qualified name?
What does setAccessible(true) on a module-encapsulated field risk?
A wrong method name passed to getMethod fails...
Next: Regular Expressions. Run the matching code in labs/src/main/java/com/jse21/m11_language/.