Class ReflectionUtils

java.lang.Object
io.fluxzero.common.reflection.ReflectionUtils

public class ReflectionUtils extends Object
Utility class for high-performance reflection-based operations across the Fluxzero Runtime.

This class is intended for internal use only. It provides a wide range of methods for accessing and manipulating object members via reflection, including:

  • Resolving annotated fields and methods (with support for meta-annotations)
  • Accessing nested property paths via getters and setters (e.g., "user/address/street")
  • Efficient member access using DefaultMemberInvoker, which leverages LambdaMetafactory for near-native invocation performance
  • Generic type resolution, including collection element types and supertype inference
  • Annotation hierarchy traversal and support for Kotlin nullability reflection (if available)
  • Utilities for determining override relationships, class hierarchies, and bean property metadata
  • Robust handling of Class loading and safe access to field/method/property values

Performance Considerations

This class uses extensive caching and memoization to avoid redundant reflective operations at runtime. All public methods are safe to use in high-performance contexts such as annotation scanning, handler dispatching, and JSON schema validation.

Modular Use

If Fluxzero adopts JPMS (Project Jigsaw) in the future, this utility would likely be placed in an internal module and not exported to consumers, to preserve encapsulation and forward compatibility.
See Also:
  • Constructor Details

    • ReflectionUtils

      public ReflectionUtils()
  • Method Details

    • getMethodOverrideHierarchy

      public static Stream<Method> getMethodOverrideHierarchy(Method method)
      Returns the method followed by the superclass and interface methods it overrides, without duplicates.
    • getParameterOverrideHierarchy

      public static Stream<Parameter> getParameterOverrideHierarchy(Parameter parameter)
      Returns the parameter at the same position throughout its method's override hierarchy, or just the supplied constructor parameter.
    • isKotlinReflectionSupported

      public static boolean isKotlinReflectionSupported()
      Returns whether the optional Kotlin reflection implementation is available on the classpath.
    • isKotlinDataClassComponent

      public static boolean isKotlinDataClassComponent(Method method)
      Whether a no-argument method is a compiler-generated Kotlin data-class component accessor. These duplicate constructor properties and should not be inferred as additional domain properties. Handwritten component methods and ordinary Java methods are not excluded.
    • ifClass

      public static Class<?> ifClass(Object value)
      Determines and returns the Class of the provided object if it is either an instance of Class or a Kotlin class that can be converted using Kotlin reflection utilities. If the object does not satisfy these conditions or Kotlin reflection is not supported, returns null.
      Parameters:
      value - The object to check and convert to Class, if possible.
      Returns:
      The Class of the provided object, or null if the object is not a class or cannot be converted.
    • isClass

      public static boolean isClass(Object value)
      Returns whether the value represents a Java class or a supported Kotlin class literal.
    • asClass

      public static Class<?> asClass(@NonNull @NonNull Object value)
      Returns the represented Java class for a class literal, or the runtime class of an ordinary object.
    • getTypeMetadata

      public static ReflectionUtils.TypeMetadata getTypeMetadata(@NonNull @NonNull Class<?> type)
      Returns the shared, class-scoped structural metadata for the given type.
    • getAllMethods

      public static List<Method> getAllMethods(Class<?> type)
      Returns the cached methods discovered across the type hierarchy.
    • getDefaultConstructor

      public static Optional<Constructor<?>> getDefaultConstructor(Class<?> type)
      Returns the default constructor declared by the supplied type, if present.
    • getAllInterfaces

      public static List<Class<?>> getAllInterfaces(Class<?> type)
      Returns all interfaces implemented by the supplied type, including interfaces inherited through superclasses and parent interfaces.
      Parameters:
      type - the type to inspect, or null
      Returns:
      interfaces in deterministic discovery order
    • box

      public static Class<?> box(Class<?> type)
      Converts a primitive type to its wrapper class and leaves non-primitive types unchanged.
      Parameters:
      type - the type to box
      Returns:
      the wrapper type for primitives, otherwise type
    • unbox

      public static Class<?> unbox(Class<?> type)
      Converts a primitive wrapper type to its primitive class and leaves other types unchanged.
      Parameters:
      type - the type to unbox
      Returns:
      the primitive type for wrappers, otherwise type
    • rawClass

      public static Class<?> rawClass(Type type)
      Resolves a reflective Type to the best raw Class representation available.
      Parameters:
      type - the reflective type to resolve
      Returns:
      the raw class, or Object when no more specific class can be resolved
    • getMethod

      public static Optional<Method> getMethod(Class<?> type, String name)
      Returns the first discovered method with the given name; parameter types are not used to select an overload.
    • getAnnotatedProperties

      public static List<? extends AccessibleObject> getAnnotatedProperties(Class<?> target, Class<? extends Annotation> annotation)
      Returns annotated fields and readable methods, deduplicated by property name, including inherited and meta-annotated properties.
    • getAnnotatedProperty

      public static Optional<? extends AccessibleObject> getAnnotatedProperty(Object target, Class<? extends Annotation> annotation)
      Returns the first matching annotated property on the target or represented class, or an empty optional for a null target.
    • getAnnotatedProperty

      public static Optional<? extends AccessibleObject> getAnnotatedProperty(Class<?> target, Class<? extends Annotation> annotation)
      Returns the first annotated property discovered for the type, or an empty optional when none matches.
    • getAnnotatedPropertyInvoker

      public static Optional<MemberInvoker> getAnnotatedPropertyInvoker(Class<?> target, Class<? extends Annotation> annotation)
      Returns a cached invoker for the first matching annotated property, with reflective access enabled.
    • getPropertyPathMetadata

      public static ReflectionUtils.TypeMetadata.PropertyPathMetadata getPropertyPathMetadata(Class<?> target, String propertyPath)
      Returns structural metadata for a nested property path; a null type or null or empty path yields missing metadata.
    • getAnnotatedPropertyValue

      public static Optional<Object> getAnnotatedPropertyValue(Object target, Class<? extends Annotation> annotation)
      Reads the first matching annotated property, returning an empty optional for a missing or null value.
    • getAnnotatedPropertyValueOrNull

      public static Object getAnnotatedPropertyValueOrNull(Object target, Class<? extends Annotation> annotation)
      Returns the value of the first property carrying the given annotation, or null when the target, annotated property, or property value is absent.

      This is the allocation-free counterpart of getAnnotatedPropertyValue(Object, Class) for callers that already use null as their absence sentinel. It uses the same centrally cached ReflectionUtils.TypeMetadata and compiled MemberInvoker.

      Parameters:
      target - target object, or null
      annotation - annotation that identifies the property
      Returns:
      the property value, or null when absent
    • getAnnotatedPropertyValues

      public static Collection<Object> getAnnotatedPropertyValues(Object target, Class<? extends Annotation> annotation)
      Reads all matching annotated properties and returns their non-null values; a null target yields an empty collection.
    • getAnnotatedPropertyName

      public static Optional<String> getAnnotatedPropertyName(Object target, Class<? extends Annotation> annotation)
      Returns the logical name of the first matching annotated property, if present.
    • getPropertyName

      public static String getPropertyName(AccessibleObject property)
      Returns a field name or derives a property name from a method, stripping conventional get and is prefixes.
    • getAnnotatedMethods

      public static List<Method> getAnnotatedMethods(Class<?> target, Class<? extends Annotation> annotation)
      Returns discovered methods carrying the annotation directly, through a meta-annotation, or through an overridden declaration.
    • getAnnotatedMethods

      public static List<Method> getAnnotatedMethods(Object target, Class<? extends Annotation> annotation)
      Returns matching annotated methods on the target's runtime class, or an empty list for a null target.
    • isMethodAnnotationPresent

      public static boolean isMethodAnnotationPresent(Executable method, Class<? extends Annotation> annotation)
      Returns whether an executable has a matching direct, meta-, or inherited method annotation.
    • getAnnotatedFields

      public static List<Field> getAnnotatedFields(Class<?> target, Class<? extends Annotation> annotation)
      Returns discovered fields carrying the annotation directly or through a meta-annotation.
    • getAnnotatedFields

      public static List<Field> getAnnotatedFields(Object target, Class<? extends Annotation> annotation)
      Returns matching annotated fields on the target or represented class, or an empty list for a null target.
    • isAnnotationPresent

      public static boolean isAnnotationPresent(Class<?> type, Class<? extends Annotation> annotationType)
      Returns whether the type, its interfaces, or an enclosing class supplies a matching annotation.
    • getTypeAnnotation

      public static <A extends Annotation> A getTypeAnnotation(Class<?> type, Class<? extends Annotation> annotationType)
      Finds a direct or composed type annotation, falling back to enclosing classes; returns null if absent. For a composed annotation, the returned instance is the outer annotation.
    • getTypeAnnotations

      public static Collection<? extends Annotation> getTypeAnnotations(Class<?> type)
      Returns the cached annotations on the type and its interfaces, deduplicated by annotation type.
    • getAnnotations

      public static List<Annotation> getAnnotations(AnnotatedElement element)
      Returns the direct annotations present on an annotated element.

      For type, field, method, constructor, and parameter elements, the result is cached in the declaring ReflectionUtils.TypeMetadata. Use getTypeAnnotations(Class) when inherited Fluxzero type annotation semantics are needed, and getPackageAnnotations(Package) for recursive package annotation lookup.

      Parameters:
      element - the annotated element to inspect
      Returns:
      annotations present on the element, or an empty list when element is null
    • getPackageAnnotation

      public static <A extends Annotation> Optional<A> getPackageAnnotation(Package p, Class<A> annotationType)
      Returns the requested annotation from the package or its enclosing package hierarchy, if present.
    • getPackageAnnotations

      public static Collection<? extends Annotation> getPackageAnnotations(Package p)
      Returns package annotations, including those discovered recursively on enclosing packages.
    • getPackageAnnotations

      public static Collection<? extends Annotation> getPackageAnnotations(Package p, boolean recursive)
      Returns package annotations, optionally including enclosing packages when recursive is true. Each package uses the first package-info definition selected by its class loader; competing definitions of the same package are not combined. For duplicate annotation types in parent packages, the nearest package wins.
    • readProperty

      public static <T> Optional<T> readProperty(String propertyPath, Object target)
      Reads a nested property path. Null targets, blank paths, missing properties, and null values yield an empty optional, including missing JSON fields and explicit JSON nulls; other access failures propagate.
    • getTypeArguments

      public static List<Type> getTypeArguments(Type genericType)
      Returns actual generic arguments for a parameterized type, or an empty list for a raw type.
    • getFirstTypeArgument

      public static <T extends Type> T getFirstTypeArgument(Type genericType)
      Returns the first actual generic argument. A raw type is rejected with IllegalArgumentException.
    • getTypeArgument

      public static <T extends Type> T getTypeArgument(Type genericType, int index)
      Returns the actual generic argument at the zero-based index. A raw type is rejected with IllegalArgumentException.
    • getPropertyAnnotation

      public static <T> Optional<T> getPropertyAnnotation(String propertyPath, Object target)
      Reads the value at a property path, returning an empty optional for a null target, missing property, or null value, including missing JSON fields and explicit JSON nulls. Despite its name, this method reads a value rather than annotation metadata.
    • hasProperty

      public static boolean hasProperty(String propertyPath, Object target)
      Returns whether the property path can be read, including a property whose value is null. Null targets and paths return false; failures other than a missing property propagate.
    • hasReturnType

      public static boolean hasReturnType(Executable executable)
      Returns whether the executable produces a result: constructors and methods whose return type is not void do.
    • getFieldValue

      public static <T> Optional<T> getFieldValue(String fieldName, Object target)
      Reads a named field with reflective access enabled, returning an empty optional for a null target, missing field, or null value.
    • getValue

      public static Object getValue(AccessibleObject fieldOrMethod, Object target, boolean forceAccess)
      Reads a field or invokes a property method on the target. forceAccess controls whether Java access checks are suppressed where permitted.
    • getValue

      public static Object getValue(AccessibleObject fieldOrMethod, Object target)
      Reads a field or invokes a property method with reflective access enabled.
    • getName

      public static String getName(AccessibleObject fieldOrMethod)
      Returns the member name; rejects accessible objects that do not represent a member.
    • getEnclosingClass

      public static Class<?> getEnclosingClass(AccessibleObject fieldOrMethod)
      Returns the class declaring the member; rejects accessible objects that do not represent a member.
    • getPropertyType

      public static Class<?> getPropertyType(AccessibleObject fieldOrMethod)
      Returns a field's declared type or a method's return type; rejects other accessible objects.
    • getGenericPropertyType

      public static Type getGenericPropertyType(AccessibleObject fieldOrMethod)
      Returns a field's generic type or a method's generic return type; rejects other accessible objects.
    • writeProperty

      public static void writeProperty(String propertyPath, Object target, Object value)
      Writes a nested property if the target and property exist. A null target or missing property is ignored; other write failures propagate.
    • isOrHas

      public static boolean isOrHas(Annotation annotation, Class<? extends Annotation> annotationType)
      Returns whether an annotation is of the requested type or directly carries that type as a meta-annotation.
    • isOrHas

      public static boolean isOrHas(Class<?> type, Class<? extends Annotation> annotationType)
      Returns whether the class is the requested annotation type or directly carries that annotation; null returns false.
    • getField

      public static Optional<Field> getField(Class<?> owner, String name)
      Returns the first discovered field with the given name, including inherited fields.
    • getCallerClass

      public static Class<?> getCallerClass()
      Returns the first calling class outside the immediate invoking class and java.*, or null if none is found.
    • isNullable

      public static boolean isNullable(Parameter parameter)
      Returns whether a parameter or an overridden declaration allows null according to nullable annotations or available Kotlin metadata.
    • asInstance

      public static <T> T asInstance(Object classOrInstance)
      Instantiates a Java or supported Kotlin class literal using its no-argument constructor; returns ordinary instances unchanged. Construction failures are wrapped in IllegalStateException.
    • getParameterIndex

      public static int getParameterIndex(Parameter parameter)
      Returns the zero-based position of the parameter in its declaring executable.
    • determineCommonAncestors

      public static List<Class<?>> determineCommonAncestors(Collection<?> elements)
      Returns common ancestor types for the runtime classes of the elements, treating null elements as Void.
    • getPackageAndParentPackages

      public static List<Package> getPackageAndParentPackages(Package p)
      Returns the package and the parent packages that can be resolved for its name.
    • getPackageAndParentPackages

      public static List<Package> getPackageAndParentPackages(Package p, Module owner)
      Returns the package and its resolvable ancestors in the owning class's module and loader. Each ancestor first resolves its own module's package-info, matching Package.getAnnotations(), then uses loader delegation when the module has no definition. Loading unrelated classes first does not change the policy. An already bound class identity remains authoritative. The thread context loader is not consulted.
      Parameters:
      p - the starting package, or null
      owner - the module of the class whose package policy is being resolved
      Returns:
      nearest packages first, omitting ancestors that cannot be resolved
    • getMemberAnnotation

      public static <A extends Annotation> Optional<A> getMemberAnnotation(Class<?> type, String memberName, Class<? extends Annotation> a)
      Finds an annotation on a method with the supplied name, falling back to a case-insensitive field-name match with an optional getter prefix removed.
    • isStatic

      public static boolean isStatic(Executable method)
      Returns whether the executable has the Java static modifier.
    • isLeafValue

      public static boolean isLeafValue(Object value)
      Returns whether the given value should be treated as a terminal scalar during reflective traversal.

      Leaf values are not recursively inspected for nested annotated properties. This is used by infrastructure such as search indexing and data protection to decide whether a value should be processed as a whole or traversed further.

      A value is considered a leaf when it is:

      • null
      • one of the built-in scalar types known to Fluxzero, such as strings, numbers, booleans, temporal values, URIs, locales, and similar primitives/value objects
      • an enum
      • an instance of a type implementing Leaf
      Parameters:
      value - the value to inspect
      Returns:
      true if the value should be treated as a leaf, false otherwise
    • isAnnotationPresent

      public static boolean isAnnotationPresent(Parameter parameter, Class<? extends Annotation> annotationType)
      Returns whether the parameter has a direct or composed annotation of the requested type.
    • getGenericType

      public static Type getGenericType(Type candidate, Class<?> wantedClass)
      Resolves a generic supertype from a parameterized declaration, preserving its argument bindings.
    • getGenericType

      public static Type getGenericType(Class<?> candidate, Class<?> wantedClass)
      Resolves the requested supertype's generic arguments in the context of the candidate class.
    • getCollectionElementType

      public static Optional<Class<?>> getCollectionElementType(AccessibleObject fieldOrMethod)
      Resolves the collection element or map value class from a field or method's generic type.
    • getCollectionElementType

      public static Optional<Class<?>> getCollectionElementType(Type parameterizedType)
      Resolves the first generic argument, or the value argument for maps, using a wildcard's upper bound. Returns Object for unresolved arguments and an empty optional for raw types.
    • declaresField

      public static boolean declaresField(Class<?> target, String fieldName)
      Returns whether the target type itself declares the named field, excluding inherited fields.
    • setField

      public static void setField(Field field, Object target, Object value)
      Assigns the field with reflective access enabled; access and assignment failures propagate.
    • setField

      public static void setField(String fieldName, Object target, Object value)
      Assigns a field declared directly on the target's class, with reflective access enabled.
    • ensureAccessible

      public static <T extends AccessibleObject> T ensureAccessible(T member)
      Enables reflective access to the member and returns it; platform access restrictions can still reject the operation.
    • getAnnotationAttributes

      public static Map<String,Object> getAnnotationAttributes(Annotation annotation)
      Returns all no-argument attributes declared by an annotation instance.
      Parameters:
      annotation - the annotation to inspect
      Returns:
      annotation attribute values keyed by attribute name
    • getAnnotationAttribute

      public static <T> Optional<T> getAnnotationAttribute(Annotation annotation, String name, Class<T> expectedType)
      Returns a single annotation attribute value when it exists and matches the requested type.
      Type Parameters:
      T - attribute value type
      Parameters:
      annotation - the annotation to inspect
      name - the attribute name
      expectedType - the expected attribute value type
      Returns:
      the attribute value, or empty if the attribute is absent or has another type
    • hasNonDefaultAnnotationAttribute

      public static boolean hasNonDefaultAnnotationAttribute(Annotation annotation, String name)
      Returns whether an annotation attribute has a value that differs from its declared default.
      Parameters:
      annotation - the annotation to inspect
      name - the attribute name
      Returns:
      true if the attribute has a default and the actual value differs from it
    • getAnnotation

      public static <A extends Annotation> Optional<A> getAnnotation(AnnotatedElement m, Class<A> a)
      Returns a direct or composed annotation, using inherited method and type lookup where applicable.
    • getAnnotationAs

      public static <T> Optional<T> getAnnotationAs(Class<?> target, Class<? extends Annotation> annotationType, Class<T> returnType)
      Finds a matching type annotation and projects its attributes into the requested representation; null or unmatched targets yield an empty optional.
    • getAnnotationAs

      public static <T> Optional<T> getAnnotationAs(AnnotatedElement member, Class<? extends Annotation> annotationType, Class<? extends T> returnType)
      Finds a matching annotation on the element and projects its attributes into the requested representation, or returns an empty optional if absent.
    • getAnnotationAs

      public static <T> Optional<T> getAnnotationAs(Annotation annotation, Class<? extends Annotation> targetAnnotation, Class<? extends T> returnType)
      Returns the annotation or its matching meta-annotation when returnType is the target annotation type. For maps and converted objects, merges meta-annotation defaults with the outer annotation's attributes, which take precedence. A null annotation or target annotation type yields an empty optional.
    • convertAnnotation

      public static <T> T convertAnnotation(Annotation annotation, Class<? extends T> returnType)
      Converts the annotation's attributes into the requested representation.
    • has

      public static boolean has(Class<? extends Annotation> annotationClass, Method method)
      Returns whether the method or an overridden declaration has the requested direct or composed annotation.
    • has

      public static boolean has(Class<? extends Annotation> annotationClass, Parameter parameter)
      Returns whether the parameter directly carries the annotation or a composed annotation of that type.
    • getFieldAnnotation

      public static <A extends Annotation> Optional<A> getFieldAnnotation(Field f, Class<? extends Annotation> a)
      Returns the field's direct or composed annotation, if present; composed matches retain the outer annotation instance.
    • getMethodAnnotation

      public static <A extends Annotation> Optional<A> getMethodAnnotation(Executable m, Class<? extends Annotation> a)
      Returns the first matching direct or composed annotation in the executable's override hierarchy.
    • getMethodAnnotations

      public static <A extends Annotation> List<A> getMethodAnnotations(Executable m, Class<? extends Annotation> a)
      Returns matching annotations from the first declaration in the override hierarchy that supplies them.
    • copyFields

      public static <V> V copyFields(V source, V target)
      Copies all non-static fields between objects of the same runtime class and returns the target. Null inputs leave the target unchanged; arrays return the source instead of copying elements.
    • classForName

      public static Class<?> classForName(String type)
      Resolves a class name through the SDK's class lookup; throws ClassNotFoundException if unresolved.
    • classForName

      public static Class<?> classForName(String type, Class<?> defaultClass)
      Resolves a class name, returning defaultClass when it cannot be resolved.
    • classExists

      public static boolean classExists(String className)
      Returns whether the SDK's class lookup can resolve the supplied class name.
    • resolveRegisteredTypeName

      public static String resolveRegisteredTypeName(String name)
      Resolves a unique registered simple or partial name to its class name. Canonical names, unknown identifiers, null and generic signatures are returned unchanged. Generic signatures do not initiate class loading. Name normalization shares the class-lookup cache; it never caches application-specific serialization aliases.
      Parameters:
      name - the serialized type identifier
      Returns:
      its uniquely registered class name, or the original identifier if no normalization is needed
    • getSimpleName

      public static String getSimpleName(Class<?> c)
      Returns the class name after its last package or nested-class separator.
    • getSimpleName

      public static String getSimpleName(Package p)
      Returns the final component of the package name.
    • getSimpleName

      public static String getSimpleName(String fullyQualifiedName)
      Returns the name after the last dot or dollar separator; null or blank names are rejected.
    • getRegisteredTypes

      public static List<Class<?>> getRegisteredTypes()
      Returns the loadable types from the generated application type registry.

      The result is resolved once and uses the same class cache as classForName(String).

    • loadClassWithoutInitialization

      public static Class<?> loadClassWithoutInitialization(String binaryName, ClassLoader classLoader) throws ClassNotFoundException
      Loads an exact binary class name without executing its static initializer or resolving serialization aliases. Uses the supplied index-owning classloader. Intended for generated structural indexes; the JVM owns class identity and getTypeMetadata(Class) owns subsequent structural reflection.
      Throws:
      ClassNotFoundException - when the named class is unavailable