Class ReflectUtil
java.lang.Object
manifold.util.ReflectUtil
A Java reflection utility. Use it to efficiently access classes by name, get/set field values,
invoke methods, and use constructors. Notable features include:
- Intuitive, fluent API
- Call any method: private, filtered, inaccessible, etc.
- Get and set the value of a final field
- Access fields and methods of a class belonging to an inaccessible module
- Call a super method
- Call a default interface method esp. for a proxy
- Call a method structurally with automatic best method matching
- Fields, methods, and constructors are cached upon use to improve performance
- Works with all versions of Java beginning with Java 8
(Use @Jailbreak to avoid writing reflection code. See Type-safe Reflection.)
-
Nested Class Summary
Nested ClassesModifier and TypeClassDescriptionstatic classstatic classstatic classstatic classstatic classstatic classstatic classUse to access live methods and fields with possible null return value if not found -
Constructor Summary
Constructors -
Method Summary
Modifier and TypeMethodDescriptionstatic booleanarePrimitiveTypesAssignable(Class toType, Class fromType) static ReflectUtil.ConstructorRefconstructor(Class<?> cls, Class<?>... params) Get aReflectUtil.ConstructorRefto the specified constructor.static ReflectUtil.ConstructorRefconstructor(String fqn, Class<?>... params) Get aReflectUtil.ConstructorRefto the specified constructor.static ReflectUtil.FieldRefGet aReflectUtil.FieldRefto the specified field.static ReflectUtil.LiveFieldRefGet aReflectUtil.LiveFieldRefto the specified field.static ReflectUtil.FieldRefGet aReflectUtil.FieldRefto the specified field.static List<ReflectUtil.LiveFieldRef> Visit declared fields of thereceiverclass.static List<ReflectUtil.LiveFieldRef> fields(Object receiver, Predicate<ReflectUtil.LiveFieldRef> filter) static MethodfindBestMethod(Method structMethod, Class receiverClass) static ObjectThis method behaves like the one below it, except this method ensures theifacedefault method is called even if thereceiveroverrides it.static ObjectinvokeDefault(Object receiver, Method method, Object... args) Invoke a default interface method.static ReflectUtil.MethodReflambdaMethod(Class<?> lambdaClass) Get aReflectUtil.MethodRefcorresponding with the functional interface implemented bylambdaClass.static ReflectUtil.MethodRefGet aReflectUtil.MethodRefto the specified method.static ReflectUtil.LiveMethodRefGet aReflectUtil.LiveMethodRefto the specified method.static ReflectUtil.MethodRefGet aReflectUtil.MethodRefto the specified method.static ReflectUtil.MethodRefmethodFromName(Class<?> cls, String name) Get aReflectUtil.MethodRefto the specifiednamewithout regard to parameter types.static voidpreloadClassIntoParentLoader(String fqn, URI content, ClassLoader wouldBeLoader, ClassLoader parentLoader) Force class with namefqnto be loaded byparentLoader.static voidstatic voidstatic voidstatic voidstatic voidUses reflection to setThread#contextClassLoaderprimarily to sidestep a bug introduced in the JDK where if aSecurityManageris set,ForkJoinPoolusesInnocuousForkJoinWorkerThreadwhich overridessetContextClassLoader()to prevent it from being used by throwing an exception.static ObjectstructuralCall(Method structMethod, Object receiver, Object... args) static ObjectstructuralCallByProxy(Method structMethod, Object proxy, Object receiver, Object... args) static ReflectUtil.MethodRefstructuralMethod(Class target, Class structIface, String name, Class... params) static ReflectUtil.LiveMethodRefstructuralMethod(Object receiver, Class structIface, String name, Class... params) static Class<?> Searches the class loader of this class for the specified name, if not found searches the current thread's context class loader.static Class<?> static Class<?> type(String fqn, ClassLoader cl) Searchesclfor the specified classfqn.static Class<?> type(String fqn, ClassLoader cl, boolean useCallChain)
-
Constructor Details
-
ReflectUtil
public ReflectUtil()
-
-
Method Details
-
type
Searches the class loader of this class for the specified name, if not found searches the current thread's context class loader.- Parameters:
fqn- The qualified name of the type e.g.,"java.lang.String"or"java.lang.String[]"- Returns:
- The
Classcorresponding withfqnor null if not found
-
type
-
type
Searchesclfor the specified classfqn.- Parameters:
fqn- The qualified name of the type e.g.,"java.lang.String"cl- The class loader to search- Returns:
- The
Classcorresponding withfqnor null if not found
-
type
-
method
Get aReflectUtil.LiveMethodRefto the specified method. Typical use:method(str, "substring", int.class).invoke(2)
- Parameters:
receiver- The object to make the call onname- The name of the method to call or a '|' separated list of names, where the first found is usedparams- The types of the method's parameters- Returns:
- A reference to the specified method, throws
RuntimeExceptionif the method is not found. UseReflectUtil.WithNullto avoid the RuntimeException.
-
method
Get aReflectUtil.MethodRefto the specified method. Typical use:method("java.time.LocalTime", "of", int.class, int.class).invokeStatic(5, 30)- Parameters:
fqn- The qualified name of the class containing the methodname- The name of the method or a '|' separated list of names, where the first found is usedparams- The types of the method's parameters- Returns:
- A reference to the specified method or null if not found
-
method
Get aReflectUtil.MethodRefto the specified method. Typical use:method(LocalTime.class, "of", int.class, int.class).invokeStatic(5, 30)
- Parameters:
cls- The class containing the methodname- The name of the method or a '|' separated list of names, where the first found is usedparams- The types of the method's parameters- Returns:
- A reference to the specified method or null if not found
-
methodFromName
Get aReflectUtil.MethodRefto the specifiednamewithout regard to parameter types. If more than one method has thename, the first one encountered is used, in no particular order. This method should be used only when the named method is not overloaded. Typical use:methodByName(LocalTime.class, "isAfter").invoke(source, time)
- Parameters:
cls- The class containing the methodname- The name of the method or a '|' separated list of names, where the first found is used- Returns:
- A reference to the specified method or null if not found
-
lambdaMethod
Get aReflectUtil.MethodRefcorresponding with the functional interface implemented bylambdaClass.lambdaMethod(function.getClass()).invoke(function, args)
- Returns:
- A reference to the specified method or null if not found
-
invokeDefault
public static Object invokeDefault(Object receiver, Class<?> iface, String name, Class<?>[] params, Object... args) This method behaves like the one below it, except this method ensures theifacedefault method is called even if thereceiveroverrides it. Essentially, this method is like calling Iface.super.method() from the receiver's perspective. -
invokeDefault
Invoke a default interface method. This is useful, for example, for a proxy implementation where there is no explicit implementation of the interface on which to invoke the default method.- Parameters:
receiver- The receiver of the call (the proxy instance in the case of a proxy impl).method- The default interface method to invoke onreceiver.args- The arguments tomethod.- Returns:
- The return value of
methodornullif the method has avoidreturn type.
-
field
Get aReflectUtil.LiveFieldRefto the specified field. Typical use:String name = field(foo, "name").get();
- Parameters:
receiver- The object having the fieldname- The name of the field or a '|' separated list of names, where the first found is used- Returns:
- A reference to the specified field, throws
RuntimeExceptionif the field is not found. UseReflectUtil.WithNullto avoid the RuntimeException.
-
field
Get aReflectUtil.FieldRefto the specified field. Typical use:field("java.time.LocalTime", "hour").get(time);- Parameters:
fqn- The qualified name of the class having the fieldname- The name of the field or a '|' separated list of names, where the first found is used- Returns:
- A reference to the specified field or null if not found
-
field
Get aReflectUtil.FieldRefto the specified field. Typical use:field(LocalTime.class, "hour").get(time);
- Parameters:
cls- The class having the fieldname- The name of the field or a '|' separated list of names, where the first found is used- Returns:
- A reference to the specified field or null if not found
-
fields
Visit declared fields of thereceiverclass. Stop iffunreturn false. -
fields
public static List<ReflectUtil.LiveFieldRef> fields(Object receiver, Predicate<ReflectUtil.LiveFieldRef> filter) -
constructor
Get aReflectUtil.ConstructorRefto the specified constructor. Typical use:constructor("java.util.ArrayList", int.class).newInstance(32)- Parameters:
fqn- The qualified name of the class to constructparams- A list of parameter types for the constructor- Returns:
- A reference to the constructor or null if not found
-
constructor
Get aReflectUtil.ConstructorRefto the specified constructor. Typical use:constructor(ArrayList.class, int.class).newInstance(32)
- Parameters:
cls- The class to constructparams- A list of parameter types for the constructor- Returns:
- A reference to the constructor or null if not found
-
setAccessible
-
setAccessible
-
setAccessible
-
setAccessible
-
preloadClassIntoParentLoader
public static void preloadClassIntoParentLoader(String fqn, URI content, ClassLoader wouldBeLoader, ClassLoader parentLoader) Force class with namefqnto be loaded byparentLoader. Facilitates the case where a class must be declared in a package defined in a parent class loader in order to subclass and use package-local features defined there.Note
fqn's natural class loader must have theparentLoaderin its chain of parent loaders. Also be certainfqnis not already loaded by its natural loader, otherwiseLinkageErrors will result.- Parameters:
fqn- The qualified name of the class to loadcontent- The location of the class resource. With Java 8 this can bewouldBeLoader.getResource(className). But with Java 9 and later the JPMS strictly prohibits a package from existing in two loaders, therefore the class file must be placed in a different package, perhaps prefixed with a suitably named root package, otherwise the VM will throw aLayerInstantiationExceptionwhen your application loads, before any of your code executes.wouldBeLoader- The class loader that would naturally loadfqn, must haveparentLoaderin its parent loader chainparentLoader- The class loader to load the class in, must be in the parent chain ofwouldBeLoader
-
structuralMethod
public static ReflectUtil.MethodRef structuralMethod(Class target, Class structIface, String name, Class... params) -
structuralMethod
public static ReflectUtil.LiveMethodRef structuralMethod(Object receiver, Class structIface, String name, Class... params) -
structuralCall
-
structuralCallByProxy
-
arePrimitiveTypesAssignable
-
findBestMethod
-
setContextClassLoader
Uses reflection to setThread#contextClassLoaderprimarily to sidestep a bug introduced in the JDK where if aSecurityManageris set,ForkJoinPoolusesInnocuousForkJoinWorkerThreadwhich overridessetContextClassLoader()to prevent it from being used by throwing an exception. It is best to use reflection to set the contextClassLoader directly. Note, the JDK issue happens when launching the IntelliJrunIdetask for plugin dev.
-