Lab 12: Reflection & Annotations

Objective

Use java.lang.reflect to inspect classes at runtime, build a custom annotation-driven SQL generator and validator, and implement a generic repository using reflection — the foundation of how ORMs like Hibernate work.

Background

Reflection lets you inspect and manipulate Java classes, fields, and methods at runtime — even private ones. Combined with custom annotations (@Retention(RUNTIME)), this enables frameworks to configure behaviour without code generation. Every major Java framework (Spring, Hibernate, JUnit) is built on these mechanisms.

Time

30 minutes

Prerequisites

  • Lab 11 (HTTP Client)

Tools

  • Docker: zchencow/innozverse-java:latest


Lab Instructions

Steps 1–8: Custom annotations, schema inspection, SQL generation, validation, generic repository, introspection, proxy, Capstone

💡 field.setAccessible(true) bypasses Java's access control — it lets you read private fields. This is how Hibernate maps table rows to private fields, and how JUnit injects test fixtures. In Java 17+, the JVM modules system may restrict this for third-party code, but within the same module it works freely. Always call it before accessing the field.

📸 Verified Output:


Summary

Reflection API
Purpose

cls.getAnnotation(A.class)

Read class-level annotation

field.getAnnotation(A.class)

Read field annotation

field.setAccessible(true)

Bypass private access

field.get(obj)

Read field value

method.invoke(obj, args)

Call method by reflection

cls.getDeclaredFields()

All fields (incl. private)

cls.getDeclaredMethods()

All methods (incl. private)

Further Reading

Last updated