Search⌘ K
AI Features

Reflection Basics

Explore how Java reflection allows programs to inspect and interact with classes, methods, and fields at runtime. Understand obtaining Class objects, creating instances dynamically, invoking methods by name, and accessing private fields. Learn about the benefits for frameworks and testing tools, as well as the risks like performance costs and loss of type safety.

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 ...