public class ReflectUtil extends Object
(Use @Jailbreak to avoid writing reflection code. See Type-safe Reflection.)
Modifier and Type | Class and Description |
---|---|
static class |
ReflectUtil.ConstructorRef |
static class |
ReflectUtil.FakeProxy |
static class |
ReflectUtil.FieldRef |
static class |
ReflectUtil.LiveFieldRef |
static class |
ReflectUtil.LiveMethodRef |
static class |
ReflectUtil.MethodRef |
static class |
ReflectUtil.WithNull
Use to access live methods and fields with possible null return value if not found
|
Constructor and Description |
---|
ReflectUtil() |
Modifier and Type | Method and Description |
---|---|
static boolean |
arePrimitiveTypesAssignable(Class toType,
Class fromType) |
static ReflectUtil.ConstructorRef |
constructor(Class<?> cls,
Class<?>... params)
Get a
ReflectUtil.ConstructorRef to the specified constructor. |
static ReflectUtil.ConstructorRef |
constructor(String fqn,
Class<?>... params)
Get a
ReflectUtil.ConstructorRef to the specified constructor. |
static ReflectUtil.FieldRef |
field(Class<?> cls,
String name)
Get a
ReflectUtil.FieldRef to the specified field. |
static ReflectUtil.LiveFieldRef |
field(Object receiver,
String name)
Get a
ReflectUtil.LiveFieldRef to the specified field. |
static ReflectUtil.FieldRef |
field(String fqn,
String name)
Get a
ReflectUtil.FieldRef to the specified field. |
static List<ReflectUtil.LiveFieldRef> |
fields(Object receiver)
Visit declared fields of the
receiver class. |
static List<ReflectUtil.LiveFieldRef> |
fields(Object receiver,
Predicate<ReflectUtil.LiveFieldRef> filter) |
static Method |
findBestMethod(Method structMethod,
Class receiverClass) |
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 the
iface default method is called even
if the receiver overrides it. |
static Object |
invokeDefault(Object receiver,
Method method,
Object... args)
Invoke a default interface method.
|
static ReflectUtil.MethodRef |
lambdaMethod(Class<?> lambdaClass)
Get a
ReflectUtil.MethodRef corresponding with the functional interface implemented by lambdaClass . |
static ReflectUtil.MethodRef |
method(Class<?> cls,
String name,
Class... params)
Get a
ReflectUtil.MethodRef to the specified method. |
static ReflectUtil.LiveMethodRef |
method(Object receiver,
String name,
Class... params)
Get a
ReflectUtil.LiveMethodRef to the specified method. |
static ReflectUtil.MethodRef |
method(String fqn,
String name,
Class... params)
Get a
ReflectUtil.MethodRef to the specified method. |
static ReflectUtil.MethodRef |
methodFromName(Class<?> cls,
String name)
Get a
ReflectUtil.MethodRef to the specified name without regard to parameter types. |
static void |
preloadClassIntoParentLoader(String fqn,
URI content,
ClassLoader wouldBeLoader,
ClassLoader parentLoader)
Force class with name
fqn to be loaded by parentLoader . |
static void |
setAccessible(Constructor c) |
static void |
setAccessible(Field f) |
static void |
setAccessible(Member m) |
static void |
setAccessible(Method m) |
static void |
setContextClassLoader(ClassLoader cl)
Uses reflection to set
Thread#contextClassLoader primarily to sidestep a bug introduced in the JDK where if
a SecurityManager is set, ForkJoinPool uses InnocuousForkJoinWorkerThread which overrides
setContextClassLoader() to prevent it from being used by throwing an exception. |
static Object |
structuralCall(Method structMethod,
Object receiver,
Object... args) |
static Object |
structuralCallByProxy(Method structMethod,
Object proxy,
Object receiver,
Object... args) |
static ReflectUtil.MethodRef |
structuralMethod(Class target,
Class structIface,
String name,
Class... params) |
static ReflectUtil.LiveMethodRef |
structuralMethod(Object receiver,
Class structIface,
String name,
Class... params) |
static Class<?> |
type(String fqn)
Searches the class loader of this class for the specified name, if not found searches
the current thread's context class loader.
|
static Class<?> |
type(String fqn,
boolean useCallChain) |
static Class<?> |
type(String fqn,
ClassLoader cl)
Searches
cl for the specified class fqn . |
static Class<?> |
type(String fqn,
ClassLoader cl,
boolean useCallChain) |
public static Class<?> type(String fqn)
fqn
- The qualified name of the type e.g., "java.lang.String"
or "java.lang.String[]"
Class
corresponding with fqn
or null if not foundpublic static Class<?> type(String fqn, ClassLoader cl)
cl
for the specified class fqn
.fqn
- The qualified name of the type e.g., "java.lang.String"
cl
- The class loader to searchClass
corresponding with fqn
or null if not foundpublic static Class<?> type(String fqn, ClassLoader cl, boolean useCallChain)
public static ReflectUtil.LiveMethodRef method(Object receiver, String name, Class... params)
ReflectUtil.LiveMethodRef
to the specified method. Typical use:
method(str, "substring", int.class).invoke(2)
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 parametersRuntimeException
if the method is not found.
Use ReflectUtil.WithNull
to avoid the RuntimeException.public static ReflectUtil.MethodRef method(String fqn, String name, Class... params)
ReflectUtil.MethodRef
to the specified method. Typical use:
method("java.time.LocalTime", "of", int.class, int.class).invokeStatic(5, 30)
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 parameterspublic static ReflectUtil.MethodRef method(Class<?> cls, String name, Class... params)
ReflectUtil.MethodRef
to the specified method. Typical use:
method(LocalTime.class, "of", int.class, int.class).invokeStatic(5, 30)
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 parameterspublic static ReflectUtil.MethodRef methodFromName(Class<?> cls, String name)
ReflectUtil.MethodRef
to the specified name
without regard to parameter types. If more than one
method has the name
, 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)
cls
- The class containing the methodname
- The name of the method or a '|' separated list of names, where the first found is usedpublic static ReflectUtil.MethodRef lambdaMethod(Class<?> lambdaClass)
ReflectUtil.MethodRef
corresponding with the functional interface implemented by lambdaClass
.
lambdaMethod(function.getClass()).invoke(function, args)
public static Object invokeDefault(Object receiver, Class<?> iface, String name, Class<?>[] params, Object... args)
iface
default method is called even
if the receiver
overrides it. Essentially, this method is like calling Iface.super.method() from the receiver's
perspective.public static Object invokeDefault(Object receiver, Method method, Object... args)
receiver
- The receiver of the call (the proxy instance in the case of a proxy impl).method
- The default interface method to invoke on receiver
.args
- The arguments to method
.method
or null
if the method has a void
return type.public static ReflectUtil.LiveFieldRef field(Object receiver, String name)
ReflectUtil.LiveFieldRef
to the specified field. Typical use:
String name = field(foo, "name").get();
receiver
- The object having the fieldname
- The name of the field or a '|' separated list of names, where the first found is usedRuntimeException
if the field is not found.
Use ReflectUtil.WithNull
to avoid the RuntimeException.public static ReflectUtil.FieldRef field(String fqn, String name)
ReflectUtil.FieldRef
to the specified field. Typical use:
field("java.time.LocalTime", "hour").get(time);
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 usedpublic static ReflectUtil.FieldRef field(Class<?> cls, String name)
ReflectUtil.FieldRef
to the specified field. Typical use:
field(LocalTime.class, "hour").get(time);
cls
- The class having the fieldname
- The name of the field or a '|' separated list of names, where the first found is usedpublic static List<ReflectUtil.LiveFieldRef> fields(Object receiver)
receiver
class. Stop if fun
return false.public static List<ReflectUtil.LiveFieldRef> fields(Object receiver, Predicate<ReflectUtil.LiveFieldRef> filter)
public static ReflectUtil.ConstructorRef constructor(String fqn, Class<?>... params)
ReflectUtil.ConstructorRef
to the specified constructor. Typical use:
constructor("java.util.ArrayList", int.class).newInstance(32)
fqn
- The qualified name of the class to constructparams
- A list of parameter types for the constructorpublic static ReflectUtil.ConstructorRef constructor(Class<?> cls, Class<?>... params)
ReflectUtil.ConstructorRef
to the specified constructor. Typical use:
constructor(ArrayList.class, int.class).newInstance(32)
cls
- The class to constructparams
- A list of parameter types for the constructorpublic static void setAccessible(Field f)
public static void setAccessible(Method m)
public static void setAccessible(Constructor c)
public static void setAccessible(Member m)
public static void preloadClassIntoParentLoader(String fqn, URI content, ClassLoader wouldBeLoader, ClassLoader parentLoader)
fqn
to be loaded by parentLoader
. 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 the parentLoader
in its chain of parent loaders.
Also be certain fqn
is not already loaded by its natural loader, otherwise LinkageError
s
will result.
fqn
- The qualified name of the class to loadcontent
- The location of the class resource. With Java 8 this can be wouldBeLoader.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 a LayerInstantiationException
when your application loads, before any of your code executes.wouldBeLoader
- The class loader that would naturally load fqn
, must have parentLoader
in its
parent loader chainparentLoader
- The class loader to load the class in, must be in the parent chain of wouldBeLoader
public static ReflectUtil.MethodRef structuralMethod(Class target, Class structIface, String name, Class... params)
public static ReflectUtil.LiveMethodRef structuralMethod(Object receiver, Class structIface, String name, Class... params)
public static Object structuralCall(Method structMethod, Object receiver, Object... args)
public static Object structuralCallByProxy(Method structMethod, Object proxy, Object receiver, Object... args)
public static boolean arePrimitiveTypesAssignable(Class toType, Class fromType)
public static void setContextClassLoader(ClassLoader cl)
Thread#contextClassLoader
primarily to sidestep a bug introduced in the JDK where if
a SecurityManager
is set, ForkJoinPool
uses InnocuousForkJoinWorkerThread
which overrides
setContextClassLoader()
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 IntelliJ runIde
task for plugin dev.Copyright © 2024. All rights reserved.