Class ConstructorInfo

All Implemented Interfaces:
Comparable<ConstructorInfo>, Annotatable

public final class ConstructorInfo extends ExecutableInfo implements Comparable<ConstructorInfo>, Annotatable
Lightweight utility class for introspecting information about a Java constructor.

This class provides a convenient wrapper around Constructor that extends the standard Java reflection API with additional functionality for constructor introspection, annotation handling, and instance creation. It extends ExecutableInfo to provide common functionality shared with methods.

Features:
  • Constructor introspection - access constructor metadata, parameters, exceptions
  • Annotation support - get annotations declared on the constructor
  • Instance creation - create new instances with type safety
  • Accessibility control - make private constructors accessible
  • Thread-safe - instances are immutable and safe for concurrent access
Use Cases:
  • Introspecting constructor metadata for code generation or analysis
  • Creating instances of classes dynamically
  • Finding annotations on constructors
  • Working with constructor parameters and exceptions
  • Building frameworks that need to instantiate objects
Usage:

// Get ConstructorInfo from a class ClassInfo ci = ClassInfo.of(MyClass.class); ConstructorInfo ctor = ci.getConstructor(String.class); // Get annotations List<AnnotationInfo<MyAnnotation>> annotations = ctor.getAnnotations(MyAnnotation.class).toList(); // Create instance ctor.accessible(); // Make accessible if private MyClass obj = ctor.invoke("arg");

See Also:
  • Constructor Details

    • ConstructorInfo

      protected ConstructorInfo(ClassInfo declaringClass, Constructor<?> inner)
      Constructor.

      Creates a new ConstructorInfo wrapper for the specified constructor. This constructor is protected and should not be called directly. Use the static factory methods of(Constructor) or obtain ConstructorInfo instances from ClassInfo.getConstructor(Constructor).

      Parameters:
      declaringClass - The ClassInfo for the class that declares this constructor. Must not be null.
      inner - The constructor being wrapped. Must not be null.
  • Method Details

    • of

      public static ConstructorInfo of(ClassInfo declaringClass, Constructor<?> inner)
      Creates a ConstructorInfo wrapper for the specified constructor.
      Example:

      ClassInfo ci = ClassInfo.of(MyClass.class); Constructor<?> c = MyClass.class.getConstructor(String.class); ConstructorInfo ci2 = ConstructorInfo.of(ci, c);

      Parameters:
      declaringClass - The ClassInfo for the class that declares this constructor. Must not be null.
      inner - The constructor being wrapped. Must not be null.
      Returns:
      A new ConstructorInfo object wrapping the constructor.
    • of

      public static ConstructorInfo of(Constructor<?> inner)
      Creates a ConstructorInfo wrapper for the specified constructor.

      This convenience method automatically determines the declaring class from the constructor.

      Example:

      Constructor<?> c = MyClass.class.getConstructor(String.class); ConstructorInfo ci = ConstructorInfo.of(c);

      Parameters:
      inner - The constructor being wrapped. Must not be null.
      Returns:
      A new ConstructorInfo object wrapping the constructor.
    • accessible

      Description copied from class: ExecutableInfo
      Attempts to call x.setAccessible(true) and quietly ignores security exceptions.
      Overrides:
      accessible in class ExecutableInfo
      Returns:
      This object.
    • compareTo

      public int compareTo(ConstructorInfo o)
      Specified by:
      compareTo in interface Comparable<ConstructorInfo>
    • getAnnotatableType

      Description copied from interface: Annotatable
      Returns the type of this annotatable object.
      Specified by:
      getAnnotatableType in interface Annotatable
      Returns:
      The type of annotatable object this represents.
    • getLabel

      public String getLabel()
      Description copied from interface: Annotatable
      Returns a human-readable label for this annotatable element.

      The label format depends on the type of annotatable:

      • CLASS_TYPE - Simple class name (e.g., "MyClass")
      • METHOD_TYPE - Class and method with parameter types (e.g., "MyClass.myMethod(String,int)")
      • FIELD_TYPE - Class and field name (e.g., "MyClass.myField")
      • CONSTRUCTOR_TYPE - Class and constructor with parameter types (e.g., "MyClass.MyClass(String)")
      • PARAMETER_TYPE - Class, method/constructor, and parameter index (e.g., "MyClass.myMethod[0]")
      • PACKAGE_TYPE - Package name (e.g., "com.example.package")
      Specified by:
      getLabel in interface Annotatable
      Returns:
      The human-readable label for this annotatable element.
    • inner

      public <T> Constructor<T> inner()
      Returns the wrapped constructor.
      Example:

      ConstructorInfo ci = ...; Constructor<MyClass> ctor = ci.inner();

      Type Parameters:
      T - The class type of the constructor.
      Returns:
      The wrapped constructor.
    • equals

      public boolean equals(Object obj)
      Compares this ConstructorInfo with the specified object for equality.

      Two ConstructorInfo objects are considered equal if they wrap the same underlying Constructor object. This delegates to the underlying Constructor.equals(Object) method.

      This method makes ConstructorInfo suitable for use as keys in hash-based collections such as HashMap and HashSet.

      Overrides:
      equals in class Object
      Parameters:
      obj - The object to compare with.
      Returns:
      true if the objects are equal, false otherwise.
    • hashCode

      public int hashCode()
      Returns a hash code value for this ConstructorInfo.

      This delegates to the underlying Constructor.hashCode() method.

      This method makes ConstructorInfo suitable for use as keys in hash-based collections such as HashMap and HashSet.

      Overrides:
      hashCode in class Object
      Returns:
      A hash code value for this ConstructorInfo.
    • newInstance

      public <T> T newInstance(Object... args) throws ExecutableException
      Shortcut for calling the new-instance method on the underlying constructor.

      If the number of formal parameters required by the underlying constructor is 0, the supplied args array may be of length 0 or null.

      Type Parameters:
      T - The constructor class type.
      Parameters:
      args - The arguments used for the constructor call. Can be null or empty for constructors with no parameters.
      Returns:
      The object returned from the constructor.
      Throws:
      ExecutableException - Exception occurred on invoked constructor/method/field.
    • newInstanceLenient

      public <T> T newInstanceLenient(Object... args) throws ExecutableException
      Shortcut for calling the new-instance method on the underlying constructor using lenient argument matching.

      Lenient matching allows arguments to be matched to parameters based on parameter types.
      Arguments can be in any order.
      Extra arguments are ignored.
      Missing arguments are set to null.

      Type Parameters:
      T - The constructor class type.
      Parameters:
      args - The arguments used for the constructor call.
      Returns:
      The object returned from the constructor.
      Throws:
      ExecutableException - Exception occurred on invoked constructor/method/field.
    • getMissingParameterTypes

      public String getMissingParameterTypes(BeanStore beanStore, Object enclosingInstance, Object... otherBeans)
      Returns comma-delimited list of missing parameter types.

      Analyzes the parameters of this constructor and checks if all required beans are available in the bean store or in the otherBeans parameter.

      The following parameter types are considered optional and are not checked:

      • Parameters of type Optional<T>
      • Parameters of type T[], List<T>, Set<T>, or Map<String,T>
      • The first parameter if it matches the enclosingInstance object type (for non-static inner classes)

      If a parameter has a @Named or @Qualifier annotation, the method checks for a bean with that specific name in the bean store. Otherwise, it checks for an unnamed bean of the parameter type in the bean store, and if not found, checks the otherBeans parameter.

      Parameters:
      beanStore - The bean store to check for beans.
      enclosingInstance - The outer class instance for non-static inner class constructors. If the first parameter type matches this object's type, it is used as the first parameter and not checked in the bean store. Can be null for regular classes or static inner classes.
      otherBeans - Optional additional bean instances to check if not found in the bean store. These are checked after the bean store but before marking the parameter as missing.
      Returns:
      A comma-delimited, sorted list of missing parameter types (e.g., "String,Integer"), or null if all required parameters are available.
    • canResolveAllParameters

      public boolean canResolveAllParameters(BeanStore beanStore, Object enclosingInstance, Object... otherBeans)
      Checks if all constructor parameters can be resolved.

      This method performs the same checks as getMissingParameterTypes(BeanStore, Object, Object...) but returns a boolean instead of a list of missing types.

      The following parameter types are considered optional and are not checked:

      • Parameters of type Optional<T>
      • Parameters of type T[], List<T>, Set<T>, or Map<String,T>
      • The first parameter if it matches the enclosingInstance object type (for non-static inner classes)

      If a parameter has a @Named or @Qualifier annotation, the method checks for a bean with that specific name in the bean store. Otherwise, it checks for an unnamed bean of the parameter type in the bean store, and if not found, checks the otherBeans parameter.

      Parameters:
      beanStore - The bean store to check for beans.
      enclosingInstance - The outer class instance for non-static inner class constructors. If the first parameter type matches this object's type, it is used as the first parameter and not checked in the bean store. Can be null for regular classes or static inner classes.
      otherBeans - Optional additional bean instances to check if not found in the bean store. These are checked after the bean store but before marking the parameter as missing.
      Returns:
      true if all required parameters are available in the bean store or otherBeans, false otherwise.
    • inject

      public <T> T inject(BeanStore beanStore, Object enclosingInstance, Object... otherBeans)
      Resolves parameters from the bean store and invokes the constructor.

      For each parameter in the constructor, this method:

      • If the first parameter type matches the enclosingInstance object type, uses the enclosingInstance object (for non-static inner class constructors).
      • If the parameter is a collection/array/map type, collects all beans of the element type.
      • Otherwise, looks up a single bean by type and optional qualifier name in the bean store.
      • If not found in the bean store, checks the otherBeans parameter.
      Parameter Resolution:
      • Single beans - Resolved using BeanStore.getBean(Class) or BeanStore.getBean(Class, String). If not found, checks otherBeans for a compatible instance. Throws ExecutableException if not found in either location.
      • Optional beans - Wrapped in Optional, or Optional.empty() if not found. Never throws an exception.
      • Arrays - All beans of the element type are collected into an array (may be empty). Never throws an exception.
      • Lists - All beans of the element type are collected into a List (may be empty). Never throws an exception.
      • Sets - All beans of the element type are collected into a LinkedHashSet (may be empty). Never throws an exception.
      • Maps - All beans of the value type are collected into a LinkedHashMap keyed by bean name (may be empty). Unnamed beans use an empty string as the key. Never throws an exception.

      The enclosingInstance parameter is used for non-static inner class constructors. If the first parameter type matches this object's type, it is used as the first parameter value. For regular constructors, this parameter is ignored if it doesn't match the first parameter type.

      Type Parameters:
      T - The return type of the constructor.
      Parameters:
      beanStore - The bean store to resolve parameters from.
      enclosingInstance - The outer class instance for non-static inner classes (can be null).
      otherBeans - Optional additional bean instances to use if not found in the bean store.
      Returns:
      The result of invoking the constructor.
      Throws:
      ExecutableException - If the constructor cannot be invoked or parameter resolution fails.