Runtime Structure Analysis via Java Reflection

The Java Reflection API provides mechanisms to examine and manipulate classes, enterfaces, fields, and methods at runtime. By leveraging java.lang.reflect descriptors, developers can dynamically inspect compiled bytecode structures without prior compilation knowledge or source code access.

Load the target type using Class.forName(). Once loaded, invoke getSuperclass() to retrieve the parent hierarchy, and pass the integer flags from getModifiers() to Modifier.toString() for human-readable accessibility decoding. Extract internal components by calling getDeclaredConstructors(), getDeclaredMethods(), and getDeclaredFields(). These calls return arrays of reflective objects representing the class's immediate members.

import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;

public class ClassInspectionTool {
    
    public static void analyze(String fullyQualifiedClassName) {
        try {
            Class<?> target = Class.forName(fullyQualifiedClassName);
            Class<?> parent = target.getSuperclass();
            
            System.out.printf("%s %s class %s\n", 
                Modifier.isPublic(target.getModifiers()) ? "public" : "",
                parent != null && parent != Object.class ? "extends " + parent.getSimpleName() : "",
                target.getSimpleName());
            System.out.println("{\n");
            
            dumpConstructors(target);
            dumpMethods(target);
            dumpMembers(target);
            
            System.out.println("}");
        } catch (ClassNotFoundException e) {
            e.printStackTrace(System.err);
        }
    }

    private static void dumpConstructors(Class<?> cls) {
        System.out.println("  -- Constructors --");
        Constructor<?>[] ctors = cls.getDeclaredConstructors();
        for (Constructor<?> ctor : ctors) {
            StringBuilder sb = new StringBuilder();
            sb.append(formatFlags(ctor.getModifiers()))
              .append(" ").append(cls.getSimpleName())
              .append("(");
            appendSignatureList(sb, ctor.getParameterTypes(), "");
            sb.append(");\n");
            System.out.print(sb);
        }
        System.out.println();
    }

    private static void dumpMethods(Class<?> cls) {
        System.out.println("  -- Methods --");
        Method[] funcs = cls.getDeclaredMethods();
        for (Method func : funcs) {
            StringBuilder line = new StringBuilder();
            line.append("  ")
                .append(formatFlags(func.getModifiers()))
                .append(" ").append(func.getReturnType().getSimpleName())
                .append(" ").append(func.getName()).append("(");
            appendSignatureList(line, func.getParameterTypes(), ", ");
            line.append(");\n");
            System.out.print(line);
        }
        System.out.println();
    }

    private static void dumpMembers(Class<?> cls) {
        System.out.println("  -- Fields --");
        Field[] attrs = cls.getDeclaredFields();
        for (Field attr : attrs) {
            StringBuilder entry = new StringBuilder();
            entry.append("  ")
                 .append(formatFlags(attr.getModifiers()))
                 .append(" ").append(attr.getType().getSimpleName())
                 .append(" ").append(attr.getName()).append(";\n");
            System.out.print(entry);
        }
    }

    private static String formatFlags(int modInt) {
        return Modifier.toString(modInt).trim();
    }

    private static void appendSignatureList(StringBuilder buf, Class<?>[] types, String sep) {
        for (int i = 0; i < types.length; i++) {
            if (i > 0) buf.append(sep);
            buf.append(types[i].getSimpleName());
        }
    }

    public static void main(String[] args) {
        analyze("java.lang.Boolean");
    }
}

Executing the routine against java.lang.Boolean produces a structured representation:

  public class Boolean extends java.lang.Object
{

  -- Constructors --
  public Boolean(boolean);

  -- Methods --
  public boolean booleanValue();
  public int compareTo(java.lang.Boolean);
  public static java.lang.Boolean parseBoolean(java.lang.String);
  public java.lang.String toString();
  public static boolean hashCode(boolean);
  ...  

  -- Fields --
  public static final java.lang.Boolean TRUE;
  public static final java.lang.Boolean FALSE;
  private final boolean value;
  private static final long serialVersionUID;
}

The reflection framework organizes runtime metadata into three primary descriptors: Constructor, Method, and Field. Each exposes standardized inspection routines that share identical naming conventions for consistent iteration. Retrieving accessibility flags requires passing the integer result of getModifiers() to Modifier.toString(). Accessing identifiers relies on getName(). Parameter resolution returns a Class<?> array via getParameterTypes(), while attribute type retrieval uses getType(). Methods extend this pattern with getReturnType() to identify the output type signature.

This unified interface design allows developers to traverse reflective collections uniformly. Weather analyzing legacy bytecode or constructing dynamic proxies, the same extraction pipeline applies. By combining class discovery with targeted member interrogation, runtime schema exploration remains reliable and independent of compile-time dependencies.

Posted on Sun, 17 May 2026 04:06:59 +0000 by amit