: Java Reflection: Runtime Class Introspection and Dynamic Operations

The Java Reflection API enables programmatic access to class structure and behavior at runtime. Central to this capability is the Class object, which acts as a prototype for every loaded type. When compile-time access is restricted, this prototype object provides a pathway for dynamic instantiation and manipulation.

Constructor Invocation Strategies

Reflection offers mulitple approaches for object instantiation, each serving different scenarios.

Sample Entity

public class Customer {
    private int customerId;
    private String fullName;
    private String registrationDate;
    private boolean verified;

    public Customer() {}

    public Customer(int id, String name, String date, boolean status) {
        this.customerId = id;
        this.fullName = name;
        this.registrationDate = date;
        this.verified = status;
    }
}

Instantiation Techniques

// Conventional approach
Customer regularCustomer = new Customer();
Customer premiumCustomer = new Customer(1001, "Alice Smith", "2024-03-15", true);

// Reflection approach
Class<?> customerClass = Class.forName("com.demo.Customer");

// Method 1: Direct class instantiation (deprecated in Java 9+)
Object basicInstance = customerClass.newInstance();

// Method 2: Explicit constructor retrieval (recommended)
Constructor<?> defaultCtor = customerClass.getDeclaredConstructor();
Object standardInstance = defaultCtor.newInstance();

// Parameterized construction
Constructor<?> customCtor = customerClass.getDeclaredConstructor(
    int.class, String.class, String.class, boolean.class
);
Object customInstance = customCtor.newInstance(1002, "Bob Johnson", "2024-03-20", false);

The getDeclaredConstructor() method retrieves constructors regardless of access modifiers, while getConstructor() only returns public constructors.

Method Execution at Runtime

Accessible Methods

Class<?> serviceClass = Class.forName("com.demo.NotificationService");
Object service = serviceClass.newInstance();
Method sendMethod = serviceClass.getMethod("sendNotification", String.class);
sendMethod.invoke(service, "Hello World");

Restricted Methods

Class<?> serviceClass = Class.forName("com.demo.NotificationService");
Object service = serviceClass.newInstance();
Method internalMethod = serviceClass.getDeclaredMethod("logEvent");
internalMethod.setAccessible(true);
internalMethod.invoke(service);

Dynamic Field Manipulation

Public Attributes

package com.demo.reflection;

import java.lang.reflect.Field;

public class FieldAccessor {
    public static void main(String[] args) throws Exception {
        Class<?> productClass = Class.forName("com.demo.reflection.Product");
        Object item = productClass.newInstance();
        
        Field nameField = productClass.getField("productName");
        System.out.println("Initial: " + nameField.get(item));
        nameField.set(item, "Laptop");
        System.out.println("Updated: " + nameField.get(item));
    }
}

Private Attributes

package com.demo.reflection;

import java.lang.reflect.Field;

public class PrivateFieldAccessor {
    public static void main(String[] args) throws Exception {
        Class<?> productClass = Class.forName("com.demo.reflection.Product");
        Object item = productClass.newInstance();
        
        Field priceField = productClass.getDeclaredField("price");
        priceField.setAccessible(true);
        System.out.println("Current price: " + priceField.get(item));
        priceField.set(item, 1299.99);
        System.out.println("Modified price: " + priceField.get(item));
    }
}

Accessing private fields requires setAccessible(true) to override Java's visbiility checks, which may raise security exceptions if the JVM security manager denies the operation.

Tags: java reflection programming runtime introspection

Posted on Mon, 27 Jul 2026 16:41:48 +0000 by simonmlewis