Master Java Reflection: From Basics to Advanced Usage

This article provides a comprehensive guide to Java's reflection mechanism, covering its definition, core capabilities, practical code examples, common API usage, and considerations such as performance and security, enabling developers to understand and apply reflection effectively in real-world projects.

Senior Brother's Insights
Senior Brother's Insights
Senior Brother's Insights
Master Java Reflection: From Basics to Advanced Usage

What Is Reflection?

Reflection is a feature of Java that allows a running program to obtain information about its own classes, fields, methods, and constructors, and to manipulate them at runtime.

Key Benefits and Drawbacks

Reflection enables dynamic object creation and method invocation, offering great flexibility for building generic frameworks. However, it can impact performance, increase code complexity, raise security concerns, and break object‑oriented principles when used indiscriminately.

Typical Use Cases

Determine the class of any object at runtime.

Instantiate objects of arbitrary classes.

Inspect and invoke methods, including private ones.

Access and modify fields, even private ones.

Invoke methods on objects dynamically.

Frameworks such as Spring rely heavily on reflection for tasks like loading bean classes from XML or annotation‑based configurations.

Simple Annotation Example

static void initUser(User user) throws IllegalAccessException {
    // Get all declared fields of User (getFields cannot retrieve private fields)
    Field[] fields = User.class.getDeclaredFields();
    for (Field field : fields) {
        // If the field has the InitSex annotation, set its value
        if (field.isAnnotationPresent(InitSex.class)) {
            InitSex init = field.getAnnotation(InitSex.class);
            field.setAccessible(true);
            field.set(user, init.sex().toString());
            System.out.println("Completed attribute modification, new value: " + init.sex().toString());
        }
    }
}

Creating Objects with Reflection vs. Direct Instantiation

Direct instantiation:

User user = new User();
user.setUsername("公众号:程序新视界");
user.setAge(3);

Reflection‑based instantiation:

@Test
public void testCreateReflect() throws ClassNotFoundException, NoSuchMethodException, IllegalAccessException, InvocationTargetException, InstantiationException {
    // Obtain the Class object for User
    Class clz = Class.forName("com.choupangxia.reflect.User");
    // Get the no‑arg constructor
    Constructor constructor = clz.getConstructor();
    // Create a new instance via the constructor
    User user = (User) constructor.newInstance();
    user.setUsername("公众号:程序新视界");
    user.setAge(3);
    System.out.println("username=" + user.getUsername());
    System.out.println("age=" + user.getAge());
}

Obtaining Class Objects

Three common ways to get a Class object:

Class.forName("com.example.MyClass") – when you know the fully qualified name.

MyClass.class – compile‑time reference.

instance.getClass() – from an existing object.

Creating Objects

Two main approaches:

Class.newInstance() – uses the default constructor.

Constructor.newInstance() – allows selection of specific constructors.

Accessing Fields, Methods, and Constructors

Fields:

Field[] fields = clz.getFields(); // public fields only
for (Field f : fields) {
    System.out.println(f.getName());
}

Field[] allFields = clz.getDeclaredFields(); // includes private fields
for (Field f : allFields) {
    System.out.println(f.getName());
}

Methods:

Method[] methods = clz.getMethods(); // includes inherited methods
for (Method m : methods) {
    System.out.println(m.getName());
}

Constructors can be retrieved with clz.getConstructor(...) or clz.getDeclaredConstructor(...) and invoked similarly.

Creating Arrays via Reflection

@Test
public void createArray() throws ClassNotFoundException {
    Class<?> cls = Class.forName("java.lang.String");
    Object array = Array.newInstance(cls, 5);
    Array.set(array, 0, "Hello");
    Array.set(array, 1, "公众号");
    Array.set(array, 2, "程序新视界");
    Array.set(array, 3, "二师兄");
    Array.set(array, 4, "Java");
    System.out.println(Array.get(array, 2)); // prints "程序新视界"
}

Conclusion

Reflection is a powerful tool for building flexible, generic frameworks, but it should be used judiciously due to its performance overhead and potential security implications. When possible, prefer conventional coding styles, reserving reflection for scenarios where dynamic behavior is essential.

Original Source

Signed-in readers can open the original source through BestHub's protected redirect.

Sign in to view source
Republication Notice

This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactadmin@besthub.devand we will review it promptly.

JavaReflectionRuntimespringAPIClassexample
Senior Brother's Insights
Written by

Senior Brother's Insights

A public account focused on workplace, career growth, team management, and self-improvement. The author is the writer of books including 'SpringBoot Technology Insider' and 'Drools 8 Rule Engine: Core Technology and Practice'.

0 followers
Reader feedback

How this landed with the community

Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.