Search⌘ K
AI Features

Reflection Basics

Explore how Java reflection allows programs to inspect and manipulate classes at runtime. Understand how to obtain Class objects, create instances dynamically, invoke methods, and access private fields. This lesson highlights reflection's use in frameworks and testing, along with its performance and safety trade-offs, helping you apply it effectively when flexibility is needed.

Most of the code we write is static: we define classes, instantiate specific types, and call known methods. The compiler checks everything beforehand. But how do tools like IntelliJ IDEA suggest methods in a pop-up as we type? Or how does JUnit run our test methods without us explicitly calling them in a main method? The answer is reflection.

Reflection allows a Java program to inspect its own structure at runtime. It lets code inspect classes, discover methods, and access fields dynamically, even if those classes were not known at compile time. In this lesson, we will explore how to use this powerful capability that trades compile-time safety for runtime flexibility.

The class entry point

The gateway to all reflection operations is the java.lang.Class class. Every object and type in Java is associated with a Class object that contains metadata about it its name, methods, fields, and constructors.

There are three primary ways to obtain a Class object:

  1. The .class literal: Used when we know the type at compile time (e.g., String.class).

  2. The getClass() method: Used on an instance to find its actual type at runtime.

  3. Class.forName(): Used to load a class using its fully qualified string name. This is the most dynamic approach, often used when class names are read from configuration files.

If the same ...