Class Reflector


  • public class Reflector
    extends Object
    Caching Java Reflection helper
    Encapsulates Constructors, Methods and Fields while providing high-level method for invoking constructors, method and getting/setting fields

    Depending on the version of Java you're using you may need to explicitly add something like the following to your Module Config or Java arguments to ensure that Reflector is allowed to perform Java reflection
    See https://docs.oracle.com/en/java/javase/17/migrate/migrating-jdk-8-later-jdk-releases.html#GUID-12F945EB-71D6-46AF-8C3D-D354FD0B1781 for more information and to understand the implications of adding the --add-opens argument.
    See Also:
    Interfaces
    • Method Detail

      • reflectOn

        public static Reflector reflectOn​(String fullyQualifiedClassName)
        Create a Reflector instance for the class with fullyQualifiedClassName
        Parameters:
        fullyQualifiedClassName - the fully qualified class name for the type we want to reflect on
        Returns:
        the Reflector instance
      • reflectOn

        public static Reflector reflectOn​(Class<?> type)
        Create a Reflector instance for the type
        Parameters:
        type - the type we want to reflect on
        Returns:
        the Reflector instance
      • hasDefaultConstructor

        public boolean hasDefaultConstructor()
        Does the type have a default no-arguments constructor?
        Returns:
        true if the type has a default no-arguments constructor, otherwise false
      • getDefaultConstructor

        public Optional<Constructor<?>> getDefaultConstructor()
        Get the default no-arguments constructor
        Returns:
        The default no-args constructor wrapped in an Optional, otherwise an Optional.empty() if no default no-args constructor exists
      • hasMatchingConstructorBasedOnArguments

        public boolean hasMatchingConstructorBasedOnArguments​(Object... constructorArguments)
        Perform constructor matching based on actual argument values (as opposed to hasMatchingConstructorBasedOnParameterTypes(Class[]))
        The constructor match doesn't require exact type matches only compatible type matches
        Parameters:
        constructorArguments - the actual argument values
        Returns:
        true if there's a single matching constructor, otherwise false
      • hasMatchingConstructorBasedOnParameterTypes

        public boolean hasMatchingConstructorBasedOnParameterTypes​(Class<?>... parameterTypes)
        Perform constructor matching based on exact parameter types (as opposed to hasMatchingConstructorBasedOnArguments(Object...))
        Parameters:
        parameterTypes - the parameter types
        Returns:
        true if there's a single matching constructor
      • newInstance

        public <T> T newInstance​(Object... constructorArguments)
        Create a new instance of the type() using a constructor that matches the constructorArguments
        The constructor matching uses the Parameters.parameterTypesMatches(Class[], Class[], boolean) without requiring an exact parameter type match
        Type Parameters:
        T - the type of the object returned
        Parameters:
        constructorArguments - the arguments for the constructor
        Returns:
        the newly created instance
        Throws:
        ReflectionException - in case something goes wrong
      • type

        public Class<?> type()
        The type wrapped by this Reflector instance
        Returns:
        The type wrapped by this Reflector instance
      • hasMethod

        public boolean hasMethod​(String methodName,
                                 boolean staticMethod,
                                 Class<?>... argumentTypes)
        Does the type wrapped by this Reflector instance have a method that matches on:
        Parameters:
        methodName - the name of the method
        staticMethod - true if the matching method MUST be a static method, otherwise it will only search instance methods
        argumentTypes - the argument types that the method must support
        Returns:
        true if the type has a matching method, otherwise false
        See Also:
        findMatchingMethod(String, boolean, Class[])
      • findMatchingMethod

        public Optional<Method> findMatchingMethod​(String methodName,
                                                   boolean staticMethod,
                                                   Class<?>... argumentTypes)
        Find the first method in the type wrapped by this Reflector instance that matches on:
        Parameters:
        methodName - the name of the method
        staticMethod - true if the matching method MUST be a static method, otherwise it will only search instance methods
        argumentTypes - the argument types that the method must support
        Returns:
        an Optional with the matching method or Optional.empty() if no matching could be made
        Throws:
        TooManyMatchingMethodsFoundException - in case there are more than 1 method that matches on the argument type
      • invokeStatic

        public <R> R invokeStatic​(Method method,
                                  Object... arguments)
        Invoke the static on the type wrapped by this Reflector instance
        Type Parameters:
        R - the return type
        Parameters:
        method - the method that will be invoked
        arguments - the arguments that will be passed to the static method.
        Returns:
        the result of invoking the static method
        Throws:
        MethodInvocationFailedException - if the method invocation fails
        See Also:
        invokeStatic(Method, Object...)
      • invoke

        public <R> R invoke​(Method method,
                            Object invokeOnObject,
                            Object... withArguments)
        Invoke the instance method on the invokeOnObject instance
        Type Parameters:
        R - the return type
        Parameters:
        method - the method that will be invoked
        invokeOnObject - the object instance that the matching method will be invoked on
        withArguments - the arguments that will be passed to the instance method.<
        Returns:
        the result of invoking the method
        Throws:
        NoMatchingMethodFoundException - if a matching method cannot be found
        MethodInvocationFailedException - if the method invocation fails
      • findFieldByName

        public Optional<Field> findFieldByName​(String fieldName)
        Find the instance Field, in the type wrapped by this Reflector instance, that matches on the field name
        Parameters:
        fieldName - the name of the field we're searching for
        Returns:
        an Optional with the matching Field, otherwise an Optional.empty() if no matching field can be found
      • findStaticFieldByName

        public Optional<Field> findStaticFieldByName​(String fieldName)
        Find the static Field, in the type wrapped by this Reflector instance, that matches on the field name
        Parameters:
        fieldName - the name of the field we're searching for
        Returns:
        an Optional with the matching Field, otherwise an Optional.empty() if no matching field can be found
      • get

        public <R> R get​(Object object,
                         String fieldName)
        Get the value of an instance field
        Type Parameters:
        R - the return type
        Parameters:
        object - the object where the field value will get read from
        fieldName - the name of the field
        Returns:
        the value of the field
        Throws:
        NoFieldFoundException - in case we couldn't find a field with a matching name in the type wrapped by this Reflector instance
        GetFieldException - in case getting the field value fails
      • get

        public <R> R get​(Object object,
                         Field field)
        Get the value of an instance field
        Type Parameters:
        R - the return type
        Parameters:
        object - the object where the field value will get read from
        field - the field to read
        Returns:
        the value of the field
        Throws:
        NoFieldFoundException - in case we couldn't find a field with a matching name
        GetFieldException - in case getting the field value fails
      • getStatic

        public <R> R getStatic​(String fieldName)
        Get the value of a static field on the type wrapped by this Reflector instance
        Type Parameters:
        R - the return type
        Parameters:
        fieldName - the name of the field
        Returns:
        the value of the field
        Throws:
        NoFieldFoundException - in case we couldn't find a field with a matching name in the type wrapped by this Reflector instance
        GetFieldException - in case getting the field value fails
      • getStatic

        public <R> R getStatic​(Field field)
        Get the value of a static field on the type wrapped by this Reflector instance
        Type Parameters:
        R - the return type
        Parameters:
        field - the static field to read
        Returns:
        the value of the field
        Throws:
        GetFieldException - in case getting the field value fails
      • set

        public void set​(Object object,
                        String fieldName,
                        Object newFieldValue)
        Set the instance field to the provided newFieldValue
        Parameters:
        object - the object where the field value will get read from
        fieldName - the name of the field
        newFieldValue - the new value of the field
        Throws:
        NoFieldFoundException - in case we couldn't find a field with a matching name in the type wrapped by this Reflector instance
        SetFieldException - in case setting the field value fails
      • set

        public void set​(Object object,
                        Field field,
                        Object newFieldValue)
        Set the instance field to the provided newFieldValue
        Parameters:
        object - the object where the field value will get read from
        field - the field on which to set a new value
        newFieldValue - the new value of the field
        Throws:
        NoFieldFoundException - in case we couldn't find a field with a matching name in the type wrapped by this Reflector instance
        SetFieldException - in case setting the field value fails
      • setStatic

        public void setStatic​(String fieldName,
                              Object newFieldValue)
        Set the static field, on the type wrapped by this Reflector instance, to the provided newFieldValue
        Parameters:
        fieldName - the name of the field
        newFieldValue - the new value of the field
        Throws:
        NoFieldFoundException - in case we couldn't find a field with a matching name in the type wrapped by this Reflector instance
        SetFieldException - in case setting the field value fails
      • setStatic

        public void setStatic​(Field field,
                              Object newFieldValue)
        Set the static field, on the type wrapped by this Reflector instance, to the provided newFieldValue
        Parameters:
        field - the field on which to set a new value
        newFieldValue - the new value of the field
        Throws:
        SetFieldException - in case setting the field value fails