Package org.joor

Class Reflect


  • public class Reflect
    extends java.lang.Object
    A wrapper for an Object or Class upon which reflective calls can be made.

    An example of using Reflect is

    
     // Static import all reflection methods to decrease verbosity
     import static org.joor.Reflect.*;
    
     // Wrap an Object / Class / class name with the on() method:
     on("java.lang.String")
     // Invoke constructors using the create() method:
     .create("Hello World")
     // Invoke methods using the call() method:
     .call("toString")
     // Retrieve the wrapped object
     
    • Nested Class Summary

      Nested Classes 
      Modifier and Type Class Description
      private static class  Reflect.NULL  
    • Field Summary

      Fields 
      Modifier and Type Field Description
      (package private) static java.lang.reflect.Constructor<java.lang.invoke.MethodHandles.Lookup> CACHED_LOOKUP_CONSTRUCTOR  
      private java.lang.Object object
      The wrapped object.
      private java.lang.Class<?> type
      The type of the wrapped object.
    • Constructor Summary

      Constructors 
      Modifier Constructor Description
      private Reflect​(java.lang.Class<?> type)  
      private Reflect​(java.lang.Class<?> type, java.lang.Object object)  
    • Method Summary

      All Methods Static Methods Instance Methods Concrete Methods Deprecated Methods 
      Modifier and Type Method Description
      static <T extends java.lang.reflect.AccessibleObject>
      T
      accessible​(T accessible)
      Conveniently render an AccessibleObject accessible.
      <P> P as​(java.lang.Class<P> proxyType)
      Create a proxy for the wrapped object allowing to typesafely invoke methods on it using a custom interface.
      <P> P as​(java.lang.Class<P> proxyType, java.lang.Class<?>... additionalInterfaces)
      Create a proxy for the wrapped object allowing to typesafely invoke methods on it using a custom interface.
      Reflect call​(java.lang.String name)
      Call a method by its name.
      Reflect call​(java.lang.String name, java.lang.Object... args)
      Call a method by its name.
      static Reflect compile​(java.lang.String name, java.lang.String content)
      Compile a class at runtime and reflect on it.
      static Reflect compile​(java.lang.String name, java.lang.String content, CompileOptions options)
      Compile a class at runtime and reflect on it.
      Reflect create()
      Call a constructor.
      Reflect create​(java.lang.Object... args)
      Call a constructor.
      boolean equals​(java.lang.Object obj)  
      private java.lang.reflect.Method exactMethod​(java.lang.String name, java.lang.Class<?>[] types)
      Searches a method with the exact same signature as desired.
      Reflect field​(java.lang.String name)
      Get a wrapped field.
      private java.lang.reflect.Field field0​(java.lang.String name)  
      java.util.Map<java.lang.String,​Reflect> fields()
      Get a Map containing field names and wrapped values for the fields' values.
      private static java.lang.Class<?> forName​(java.lang.String name)
      Load a class
      private static java.lang.Class<?> forName​(java.lang.String name, java.lang.ClassLoader classLoader)  
      <T> T get()
      Get the wrapped object
      <T> T get​(java.lang.String name)
      Get a field value.
      int hashCode()  
      static <T> T initValue​(java.lang.Class<T> type)
      Get the initialisation or default value for any given type.
      private boolean isSimilarSignature​(java.lang.reflect.Method possiblyMatchingMethod, java.lang.String desiredMethodName, java.lang.Class<?>[] desiredParamTypes)
      Determines if a method has a "similar" signature, especially if wrapping primitive argument types would result in an exactly matching signature.
      private boolean match​(java.lang.Class<?>[] declaredTypes, java.lang.Class<?>[] actualTypes)
      Check whether two arrays of types match, converting primitive types to their corresponding wrappers.
      static Reflect on​(java.lang.Class<?> clazz)
      Deprecated.
      [#78] 0.9.11, use onClass(Class) instead.
      private static Reflect on​(java.lang.Class<?> type, java.lang.Object object)  
      static Reflect on​(java.lang.Object object)
      Wrap an object.
      private static Reflect on​(java.lang.reflect.Constructor<?> constructor, java.lang.Object... args)
      Wrap an object created from a constructor
      private static Reflect on​(java.lang.reflect.Method method, java.lang.Object object, java.lang.Object... args)
      Wrap an object returned from a method
      static Reflect on​(java.lang.String name)
      Deprecated.
      [#78] 0.9.11, use onClass(String) instead.
      static Reflect on​(java.lang.String name, java.lang.ClassLoader classLoader)
      Deprecated.
      [#78] 0.9.11, use onClass(String, ClassLoader) instead.
      static Reflect onClass​(java.lang.Class<?> clazz)
      Wrap a class.
      static Reflect onClass​(java.lang.String name)
      Wrap a class name.
      static Reflect onClass​(java.lang.String name, java.lang.ClassLoader classLoader)
      Wrap a class name, loading it via a given class loader.
      static void process​(java.lang.String name, java.lang.String content)
      Annotation-process a class at runtime.
      static void process​(java.lang.String name, java.lang.String content, CompileOptions options)
      Annotation-process a class at runtime.
      private static java.lang.String property​(java.lang.String string)
      Get the POJO property name of an getter/setter
      Reflect set​(java.lang.String name, java.lang.Object value)
      Set a field value.
      private java.lang.reflect.Method similarMethod​(java.lang.String name, java.lang.Class<?>[] types)
      Searches a method with a similar signature as desired using isSimilarSignature(java.lang.reflect.Method, String, Class[]).
      java.lang.String toString()  
      java.lang.Class<?> type()
      Get the type of the wrapped object.
      private static java.lang.Class<?>[] types​(java.lang.Object... values)
      Get an array of types for an array of objects
      private static java.lang.Object unwrap​(java.lang.Object object)
      Unwrap an object
      static <T> java.lang.Class<T> wrapper​(java.lang.Class<T> type)
      Get a wrapper type for a primitive type, or the argument type itself, if it is not a primitive type.
      • Methods inherited from class java.lang.Object

        clone, finalize, getClass, notify, notifyAll, wait, wait, wait
    • Field Detail

      • CACHED_LOOKUP_CONSTRUCTOR

        static final java.lang.reflect.Constructor<java.lang.invoke.MethodHandles.Lookup> CACHED_LOOKUP_CONSTRUCTOR
      • type

        private final java.lang.Class<?> type
        The type of the wrapped object.
      • object

        private final java.lang.Object object
        The wrapped object.
    • Constructor Detail

      • Reflect

        private Reflect​(java.lang.Class<?> type)
      • Reflect

        private Reflect​(java.lang.Class<?> type,
                        java.lang.Object object)
    • Method Detail

      • compile

        public static Reflect compile​(java.lang.String name,
                                      java.lang.String content)
                               throws ReflectException
        Compile a class at runtime and reflect on it.

        For example:

        
         Supplier<String> supplier = Reflect.compile("org.joor.Test", """
           package org.joor;
           class Test implements java.util.function.Supplier<String> {
             public String get() {
               return "Hello World!";
             }
           }
           """).create().get();
         
        Parameters:
        name - The qualified class name
        content - The source code for the class
        Returns:
        A wrapped Class
        Throws:
        ReflectException - if anything went wrong compiling the class.
      • compile

        public static Reflect compile​(java.lang.String name,
                                      java.lang.String content,
                                      CompileOptions options)
                               throws ReflectException
        Compile a class at runtime and reflect on it.

        For example:

        
         Supplier<String> supplier = Reflect.compile("org.joor.Test", """
           package org.joor;
           class Test implements java.util.function.Supplier<String> {
             public String get() {
               return "Hello World!";
             }
           }
           """).create().get();
         
        Parameters:
        name - The qualified class name
        content - The source code for the class
        options - compiler options
        Returns:
        A wrapped Class
        Throws:
        ReflectException - if anything went wrong compiling the class.
      • process

        public static void process​(java.lang.String name,
                                   java.lang.String content)
                            throws ReflectException
        Annotation-process a class at runtime.

        This works like compile(String, String), but adds the -proc:only CompileOptions and thus does not produce any compilation output.

        For example:

        
         Supplier<String> supplier = Reflect.compile("org.joor.Test", """
           package org.joor;
           @MyAnnotation
           class Test implements java.util.function.Supplier<String> {
             public String get() {
               return "Hello World!";
             }
           }
           """).create().get();
         
        Parameters:
        name - The qualified class name
        content - The source code for the class
        Throws:
        ReflectException - if anything went wrong compiling the class.
      • process

        public static void process​(java.lang.String name,
                                   java.lang.String content,
                                   CompileOptions options)
                            throws ReflectException
        Annotation-process a class at runtime.

        This works like compile(String, String), but adds the -proc:only CompileOptions and thus does not produce any compilation output.

        For example:

        
         Supplier<String> supplier = Reflect.compile("org.joor.Test", """
           package org.joor;
           @MyAnnotation
           class Test implements java.util.function.Supplier<String> {
             public String get() {
               return "Hello World!";
             }
           }
           """).create().get();
         
        Parameters:
        name - The qualified class name
        content - The source code for the class
        options - compiler options
        Throws:
        ReflectException - if anything went wrong compiling the class.
      • on

        @Deprecated
        public static Reflect on​(java.lang.String name)
                          throws ReflectException
        Deprecated.
        [#78] 0.9.11, use onClass(String) instead.
        Wrap a class name.

        This is the same as calling on(Class.forName(name))

        Parameters:
        name - A fully qualified class name
        Returns:
        A wrapped class object, to be used for further reflection.
        Throws:
        ReflectException - If any reflection exception occurred.
        See Also:
        onClass(Class)
      • on

        @Deprecated
        public static Reflect on​(java.lang.String name,
                                 java.lang.ClassLoader classLoader)
                          throws ReflectException
        Deprecated.
        [#78] 0.9.11, use onClass(String, ClassLoader) instead.
        Wrap a class name, loading it via a given class loader.

        This is the same as calling on(Class.forName(name, classLoader))

        Parameters:
        name - A fully qualified class name.
        classLoader - The class loader in whose context the class should be loaded.
        Returns:
        A wrapped class object, to be used for further reflection.
        Throws:
        ReflectException - If any reflection exception occurred.
        See Also:
        onClass(Class)
      • on

        @Deprecated
        public static Reflect on​(java.lang.Class<?> clazz)
        Deprecated.
        [#78] 0.9.11, use onClass(Class) instead.
        Wrap a class.

        Use this when you want to access static fields and methods on a Class object, or as a basis for constructing objects of that class using create(Object...)

        Parameters:
        clazz - The class to be wrapped
        Returns:
        A wrapped class object, to be used for further reflection.
      • onClass

        public static Reflect onClass​(java.lang.String name)
                               throws ReflectException
        Wrap a class name.

        This is the same as calling onClass(Class.forName(name))

        Parameters:
        name - A fully qualified class name
        Returns:
        A wrapped class object, to be used for further reflection.
        Throws:
        ReflectException - If any reflection exception occurred.
        See Also:
        onClass(Class)
      • onClass

        public static Reflect onClass​(java.lang.String name,
                                      java.lang.ClassLoader classLoader)
                               throws ReflectException
        Wrap a class name, loading it via a given class loader.

        This is the same as calling onClass(Class.forName(name, classLoader))

        Parameters:
        name - A fully qualified class name.
        classLoader - The class loader in whose context the class should be loaded.
        Returns:
        A wrapped class object, to be used for further reflection.
        Throws:
        ReflectException - If any reflection exception occurred.
        See Also:
        onClass(Class)
      • onClass

        public static Reflect onClass​(java.lang.Class<?> clazz)
        Wrap a class.

        Use this when you want to access static fields and methods on a Class object, or as a basis for constructing objects of that class using create(Object...)

        Parameters:
        clazz - The class to be wrapped
        Returns:
        A wrapped class object, to be used for further reflection.
      • on

        public static Reflect on​(java.lang.Object object)
        Wrap an object.

        Use this when you want to access instance fields and methods on any Object

        Parameters:
        object - The object to be wrapped
        Returns:
        A wrapped object, to be used for further reflection.
      • on

        private static Reflect on​(java.lang.Class<?> type,
                                  java.lang.Object object)
      • initValue

        public static <T> T initValue​(java.lang.Class<T> type)
        Get the initialisation or default value for any given type.

        This returns:

        • null for reference types (including wrapper types)
        • 0 for numeric primitive types (including char)
        • false for the boolean primitive type.
      • accessible

        public static <T extends java.lang.reflect.AccessibleObject> T accessible​(T accessible)
        Conveniently render an AccessibleObject accessible.

        To prevent SecurityException, this is only done if the argument object and its declaring class are non-public.

        Parameters:
        accessible - The object to render accessible
        Returns:
        The argument object rendered accessible
      • get

        public <T> T get()
        Get the wrapped object
        Type Parameters:
        T - A convenience generic parameter for automatic unsafe casting
      • set

        public Reflect set​(java.lang.String name,
                           java.lang.Object value)
                    throws ReflectException
        Set a field value.

        This is roughly equivalent to Field.set(Object, Object). If the wrapped object is a Class, then this will set a value to a static member field. If the wrapped object is any other Object, then this will set a value to an instance member field.

        This method is also capable of setting the value of (static) final fields. This may be convenient in situations where no SecurityManager is expected to prevent this, but do note that (especially static) final fields may already have been inlined by the javac and/or JIT and relevant code deleted from the runtime verison of your program, so setting these fields might not have any effect on your execution.

        For restrictions of usage regarding setting values on final fields check: http://stackoverflow.com/questions/3301635/change-private-static-final-field-using-java-reflection ... and http://pveentjer.blogspot.co.at/2017/01/final-static-boolean-jit.html

        Parameters:
        name - The field name
        value - The new field value
        Returns:
        The same wrapped object, to be used for further reflection.
        Throws:
        ReflectException - If any reflection exception occurred.
      • get

        public <T> T get​(java.lang.String name)
                  throws ReflectException
        Get a field value.

        This is roughly equivalent to Field.get(Object). If the wrapped object is a Class, then this will get a value from a static member field. If the wrapped object is any other Object, then this will get a value from an instance member field.

        If you want to "navigate" to a wrapped version of the field, use field(String) instead.

        Parameters:
        name - The field name
        Returns:
        The field value
        Throws:
        ReflectException - If any reflection exception occurred.
        See Also:
        field(String)
      • field

        public Reflect field​(java.lang.String name)
                      throws ReflectException
        Get a wrapped field.

        This is roughly equivalent to Field.get(Object). If the wrapped object is a Class, then this will wrap a static member field. If the wrapped object is any other Object, then this wrap an instance member field.

        Parameters:
        name - The field name
        Returns:
        The wrapped field
        Throws:
        ReflectException - If any reflection exception occurred.
      • fields

        public java.util.Map<java.lang.String,​Reflect> fields()
        Get a Map containing field names and wrapped values for the fields' values.

        If the wrapped object is a Class, then this will return static fields. If the wrapped object is any other Object, then this will return instance fields.

        These two calls are equivalent

        
         on(object).field("myField");
         on(object).fields().get("myField");
         
        Returns:
        A map containing field names and wrapped values.
      • call

        public Reflect call​(java.lang.String name)
                     throws ReflectException
        Call a method by its name.

        This is a convenience method for calling call(name, new Object[0])

        Parameters:
        name - The method name
        Returns:
        The wrapped method result or the same wrapped object if the method returns void, to be used for further reflection.
        Throws:
        ReflectException - If any reflection exception occurred.
        See Also:
        call(String, Object...)
      • call

        public Reflect call​(java.lang.String name,
                            java.lang.Object... args)
                     throws ReflectException
        Call a method by its name.

        This is roughly equivalent to Method.invoke(Object, Object...). If the wrapped object is a Class, then this will invoke a static method. If the wrapped object is any other Object, then this will invoke an instance method.

        Just like Method.invoke(Object, Object...), this will try to wrap primitive types or unwrap primitive type wrappers if applicable. If several methods are applicable, by that rule, the first one encountered is called. i.e. when calling

        
         on(...).call("method", 1, 1);
         
        The first of the following methods will be called:
        
         public void method(int param1, Integer param2);
         public void method(Integer param1, int param2);
         public void method(Number param1, Number param2);
         public void method(Number param1, Object param2);
         public void method(int param1, Object param2);
         

        The best matching method is searched for with the following strategy:

        1. public method with exact signature match in class hierarchy
        2. non-public method with exact signature match on declaring class
        3. public method with similar signature in class hierarchy
        4. non-public method with similar signature on declaring class
        Parameters:
        name - The method name
        args - The method arguments
        Returns:
        The wrapped method result or the same wrapped object if the method returns void, to be used for further reflection.
        Throws:
        ReflectException - If any reflection exception occurred.
      • exactMethod

        private java.lang.reflect.Method exactMethod​(java.lang.String name,
                                                     java.lang.Class<?>[] types)
                                              throws java.lang.NoSuchMethodException
        Searches a method with the exact same signature as desired.

        If a public method is found in the class hierarchy, this method is returned. Otherwise a private method with the exact same signature is returned. If no exact match could be found, we let the NoSuchMethodException pass through.

        Throws:
        java.lang.NoSuchMethodException
      • similarMethod

        private java.lang.reflect.Method similarMethod​(java.lang.String name,
                                                       java.lang.Class<?>[] types)
                                                throws java.lang.NoSuchMethodException
        Searches a method with a similar signature as desired using isSimilarSignature(java.lang.reflect.Method, String, Class[]).

        First public methods are searched in the class hierarchy, then private methods on the declaring class. If a method could be found, it is returned, otherwise a NoSuchMethodException is thrown.

        Throws:
        java.lang.NoSuchMethodException
      • isSimilarSignature

        private boolean isSimilarSignature​(java.lang.reflect.Method possiblyMatchingMethod,
                                           java.lang.String desiredMethodName,
                                           java.lang.Class<?>[] desiredParamTypes)
        Determines if a method has a "similar" signature, especially if wrapping primitive argument types would result in an exactly matching signature.
      • create

        public Reflect create()
                       throws ReflectException
        Call a constructor.

        This is a convenience method for calling create(new Object[0])

        Returns:
        The wrapped new object, to be used for further reflection.
        Throws:
        ReflectException - If any reflection exception occurred.
        See Also:
        create(Object...)
      • create

        public Reflect create​(java.lang.Object... args)
                       throws ReflectException
        Call a constructor.

        This is roughly equivalent to Constructor.newInstance(Object...). If the wrapped object is a Class, then this will create a new object of that class. If the wrapped object is any other Object, then this will create a new object of the same type.

        Just like Constructor.newInstance(Object...), this will try to wrap primitive types or unwrap primitive type wrappers if applicable. If several constructors are applicable, by that rule, the first one encountered is called. i.e. when calling

        
         on(C.class).create(1, 1);
         
        The first of the following constructors will be applied:
        
         public C(int param1, Integer param2);
         public C(Integer param1, int param2);
         public C(Number param1, Number param2);
         public C(Number param1, Object param2);
         public C(int param1, Object param2);
         
        Parameters:
        args - The constructor arguments
        Returns:
        The wrapped new object, to be used for further reflection.
        Throws:
        ReflectException - If any reflection exception occurred.
      • as

        public <P> P as​(java.lang.Class<P> proxyType)
        Create a proxy for the wrapped object allowing to typesafely invoke methods on it using a custom interface.
        Parameters:
        proxyType - The interface type that is implemented by the proxy
        Returns:
        A proxy for the wrapped object
      • as

        public <P> P as​(java.lang.Class<P> proxyType,
                        java.lang.Class<?>... additionalInterfaces)
        Create a proxy for the wrapped object allowing to typesafely invoke methods on it using a custom interface.
        Parameters:
        proxyType - The interface type that is implemented by the proxy
        additionalInterfaces - Additional interfaces that are implemented by the proxy
        Returns:
        A proxy for the wrapped object
      • property

        private static java.lang.String property​(java.lang.String string)
        Get the POJO property name of an getter/setter
      • match

        private boolean match​(java.lang.Class<?>[] declaredTypes,
                              java.lang.Class<?>[] actualTypes)
        Check whether two arrays of types match, converting primitive types to their corresponding wrappers.
      • hashCode

        public int hashCode()
        Overrides:
        hashCode in class java.lang.Object
      • equals

        public boolean equals​(java.lang.Object obj)
        Overrides:
        equals in class java.lang.Object
      • toString

        public java.lang.String toString()
        Overrides:
        toString in class java.lang.Object
      • on

        private static Reflect on​(java.lang.reflect.Constructor<?> constructor,
                                  java.lang.Object... args)
                           throws ReflectException
        Wrap an object created from a constructor
        Throws:
        ReflectException
      • on

        private static Reflect on​(java.lang.reflect.Method method,
                                  java.lang.Object object,
                                  java.lang.Object... args)
                           throws ReflectException
        Wrap an object returned from a method
        Throws:
        ReflectException
      • unwrap

        private static java.lang.Object unwrap​(java.lang.Object object)
        Unwrap an object
      • types

        private static java.lang.Class<?>[] types​(java.lang.Object... values)
        Get an array of types for an array of objects
        See Also:
        Object.getClass()
      • forName

        private static java.lang.Class<?> forName​(java.lang.String name)
                                           throws ReflectException
        Load a class
        Throws:
        ReflectException
        See Also:
        Class.forName(String)
      • forName

        private static java.lang.Class<?> forName​(java.lang.String name,
                                                  java.lang.ClassLoader classLoader)
                                           throws ReflectException
        Throws:
        ReflectException
      • type

        public java.lang.Class<?> type()
        Get the type of the wrapped object.
        See Also:
        Object.getClass()
      • wrapper

        public static <T> java.lang.Class<T> wrapper​(java.lang.Class<T> type)
        Get a wrapper type for a primitive type, or the argument type itself, if it is not a primitive type.