Reflection with Arrays, Enums, and Inner Classes in Java with Examples and Best Practices

Illustration for Reflection with Arrays, Enums, and Inner Classes in Java with Examples and Best Practices
By Last updated:

A common mistake developers make when learning Reflection is focusing only on classes and methods, while ignoring special types like arrays, enums, and inner classes. This often leads to runtime surprises—for example, trying to dynamically create arrays with reflection or accessing enum constants incorrectly.

In real-world scenarios:

  • Arrays are dynamically created when frameworks serialize JSON/XML into objects.
  • Enums are heavily used in ORM frameworks like Hibernate for mapping database values.
  • Inner classes appear in dependency injection and test utilities where nested structures are common.

Reflection for these structures is like having x-ray vision into specialized rooms of a building—you not only see the walls (classes) but also how the storage boxes (arrays), labeled drawers (enums), and hidden compartments (inner classes) are structured. Mastering them helps you write frameworks and utilities with far more flexibility.


Working with Arrays via Reflection

Creating and Accessing Arrays

import java.lang.reflect.Array;

public class ArrayReflectionExample {
    public static void main(String[] args) {
        // Create an array of Strings using reflection
        Object stringArray = Array.newInstance(String.class, 3);
        Array.set(stringArray, 0, "Apple");
        Array.set(stringArray, 1, "Banana");
        Array.set(stringArray, 2, "Cherry");

        for (int i = 0; i < Array.getLength(stringArray); i++) {
            System.out.println(Array.get(stringArray, i));
        }
    }
}

Output:

Apple
Banana
Cherry

Real-World Use

  • JSON libraries like Jackson dynamically allocate arrays for deserialization.
  • Testing frameworks generate arrays of mock objects dynamically.

Working with Enums via Reflection

Accessing Enum Constants

enum Status {
    ACTIVE, INACTIVE, PENDING;
}

public class EnumReflectionExample {
    public static void main(String[] args) throws Exception {
        Class<?> enumClass = Status.class;

        Object[] constants = enumClass.getEnumConstants();
        for (Object constant : constants) {
            System.out.println(constant);
        }

        // Get a specific enum constant by name
        Object active = Enum.valueOf((Class<Enum>) enumClass, "ACTIVE");
        System.out.println("Retrieved constant: " + active);
    }
}

Output:

ACTIVE
INACTIVE
PENDING
Retrieved constant: ACTIVE

Real-World Use

  • Hibernate maps enums to database values using reflection.
  • Spring reads enum-based configuration properties dynamically.

Working with Inner Classes via Reflection

Accessing Inner Classes

class Outer {
    class Inner {
        public void sayHello() {
            System.out.println("Hello from Inner class!");
        }
    }
}

public class InnerClassReflectionExample {
    public static void main(String[] args) throws Exception {
        Class<?> outerClass = Outer.class;
        Class<?>[] innerClasses = outerClass.getDeclaredClasses();

        for (Class<?> inner : innerClasses) {
            System.out.println("Inner class: " + inner.getName());

            Object outerInstance = outerClass.getDeclaredConstructor().newInstance();
            Object innerInstance = inner.getDeclaredConstructor(outerClass).newInstance(outerInstance);
            inner.getMethod("sayHello").invoke(innerInstance);
        }
    }
}

Output:

Inner class: Outer$Inner
Hello from Inner class!

Real-World Use

  • Dependency injection frameworks instantiate nested classes for configuration.
  • JUnit often generates nested test classes dynamically.

📌 What's New in Java Versions?

  • Java 5 – Introduced enums and improved reflection API.
  • Java 8 – Added method parameter reflection and lambda support.
  • Java 9 – Stricter access rules under modules impacted reflective access for inner classes.
  • Java 11 – No significant reflection changes for arrays/enums/inner classes.
  • Java 17 – Strong encapsulation further restricted reflective access.
  • Java 21 – No major updates specific to arrays, enums, or inner classes.

Pitfalls and Best Practices

Pitfalls

  • Forgetting that arrays created via reflection return Object, requiring casting.
  • Misusing enums by trying to instantiate them via reflection (not allowed).
  • Accessing private inner classes without setAccessible(true) fails under strict security.

Best Practices

  • Use Array API for safe array handling.
  • For enums, always rely on getEnumConstants() instead of hacking constructors.
  • Handle inner classes carefully—always instantiate with an enclosing instance when required.
  • Document reflection-heavy utilities for maintainability.

Summary + Key Takeaways

  • Reflection extends beyond classes and methods—it supports arrays, enums, and inner classes.
  • Arrays can be created and manipulated dynamically with Array class.
  • Enums are accessible with getEnumConstants() and Enum.valueOf().
  • Inner classes require an enclosing instance for instantiation.
  • These features are vital in frameworks for ORM mapping, dependency injection, and dynamic testing.

FAQ

  1. Can I instantiate an enum using reflection?
    No, enums cannot be instantiated directly; use Enum.valueOf().

  2. What’s the difference between Array.newInstance() and regular array creation?
    Reflection allows dynamic creation at runtime, while regular syntax is static.

  3. How do I get all inner classes of a class?
    Use Class.getDeclaredClasses().

  4. Can reflection access private inner classes?
    Yes, but you may need setAccessible(true), restricted in Java 9+.

  5. Are reflection-based arrays type-safe?
    No, they return Object; you must cast properly.

  6. Can enums be extended with reflection?
    No, enums in Java are final.

  7. How does Hibernate use enums with reflection?
    It reads enum constants and maps them to database values.

  8. Can I create static inner class instances with reflection?
    Yes, unlike non-static inner classes, they don’t require an enclosing instance.

  9. What’s the performance impact of reflection with arrays and enums?
    Slightly slower than direct access, but acceptable for framework-level usage.

  10. Can inner class constructors be called without an outer instance?
    Only if the inner class is static; otherwise, an outer instance is required.