public final class JReflect extends Object
java.lang.reflect. Specifically, this reflection tool is designed to perform
advanced method or constructor lookups, using a combination of JReflect.LookupMode strategies.
Aside from that there are some nifty methods for things such as:
isPackage(String)),widestNumberClass(Number...)),autobox(Class)),FieldUtils),Object, such as list of methods, properties or typesClass lookup (locateClass(String, boolean, ExternalClassLoader)), that allows a full scan (to try all
packages known) and an optional ExternalClassLoader instance that is able to actually compile a .java file on the fly and load its compile
.class file
An expanded version of getConstructor is implemented that tries to find a constructor of a given datatype, with a given argument
datatypelist, where types do not have to match formal types (auto-boxing, supertypes, implemented interfaces and type conversions are allowed as
they are included in the lookup cycles). This expanded version tries a simple call first (exact match, which is provided natively by the Java) and
when this fails, it generates a list of datatype arrays (signatures) with all possible versions of any type in the original list possible, and
combinations thereof.
Observe the following (trivial) example:
interface Foo {
void foo(Double value, Fruit fruit, char c);
}
abstract class A implements Foo {
}
abstract class B extends A {
}
JReflect.findCompatibleJavaMethod(B.class, "foo", EnumSet.allOf(LookupMode.class), double.class, Pear.class, String.class)}
In the above example, the method foo will be found by finding all methods named "Foo" on the interfaces implemented by supertype A,
and then foo's method signature will be matched using autoboxing on the double type, a cast to the Fruit supertype for
the Pear type and finally by attempting a common conversion from String to char. This will give you a Java
Method, but you won't be able to invoke it if it was found using a less strict lookup than one with a simple exact match. There are two
ways to do this: use invokeCompatibleMethod(Object, Class, String, Object...) instead or perform the conversion yourself using
ValueConverter.convert(Object[], Class[], boolean) prior to invoking the method.
ValueConverter.convert(args, method.getParameterTypes()).
// TODO fix comment about switching the cache
Because this lookup is potentially very expensive, a cache is present to store lookup results. This cache is turned on/off using the constructor.
Types that are candidates for Autoboxing:
java.lang.Booleanjava.lang.Characterjava.lang.Bytejava.lang.Shortjava.lang.Integerjava.lang.Longjava.lang.Floatjava.lang.Double
For types that are candidates for common conversion, please see ValueConverter.
FIXME make JReflect cache optional
ValueConverter,
FieldUtils,
ExternalClassLoader| Modifier and Type | Class and Description |
|---|---|
static class |
JReflect.LookupMode
Defines lookup modes for matching Java methods and constructors.
|
| Modifier and Type | Method and Description |
|---|---|
static Object |
assignToField(Object o,
String property,
Object value)
Assigns a value to a field
id on the given object o. |
static Class<?> |
autobox(Class<?> c)
Emulates Java's Autoboxing feature; tries to convert a type to its (un)wrapped counter version.
|
static Set<String> |
collectMethods(Object subject,
boolean publicOnly)
Returns a list of names that represent the methods on an
Object |
static Collection<String> |
collectProperties(Object subject)
Returns a list of names that represent the fields on an
Object. |
static Class<?>[] |
collectTypes(Object[] objects)
Creates a new array of class objects harvested from an array of objects.
|
static <T> Constructor<T> |
findCompatibleConstructor(Class<T> datatype,
EnumSet<JReflect.LookupMode> lookupMode,
Class<?>... types)
Tries to find a
Constructor of a given type, with a given typelist, where types do not match due to formal types simple types. |
static Method |
findCompatibleMethod(Class<?> datatype,
String methodName,
EnumSet<JReflect.LookupMode> lookupMode,
Class<?>... signature)
Same as
getConstructor(), except for getting a Method of a classtype, using the name to indicate which method should be
located. |
static Method |
findSimpleCompatibleMethod(Class<?> datatype,
String methodName,
Class<?>... signature)
Delegates to
findCompatibleMethod(Class, String, EnumSet, Class...), using strict lookupmode (no autoboxing, casting etc.) and
optional signature parameters. |
static Method |
getMethod(Class<?> datatype,
String name,
Class<?>... signature)
Searches a specific class object for a
Method using java reflect using a specific signature. |
static <T> T |
invokeCompatibleConstructor(Class<T> datatype,
Object... args)
Locates and invokes a
Constructorusing invokeConstructor(Class, Class[], Object[]) |
static <T> T |
invokeCompatibleMethod(Object context,
Class<?> datatype,
String identifier,
Object... args)
Locates a method on an Object using serveral searchmodes for optimization.
|
static <T> T |
invokeConstructor(Class<T> datatype,
Class<?>[] signature,
Object[] args)
Locates and invokes a
Constructor, using a customized typelist. |
static boolean |
isPackage(String name)
Validates whether a string represents a valid package.
|
static Class<?> |
locateClass(String className,
boolean fullscan,
ExternalClassLoader classLoader)
Delegates to
locateClass(String, ExternalClassLoader), using default cache. |
static Class<?> |
locateClass(String className,
boolean fullscan,
ExternalClassLoader classLoader,
boolean useCache)
Searches the JVM and optionally all of its packages
|
static Class<?> |
locateClass(String fullClassName,
ExternalClassLoader classLoader)
This function dynamically tries to locate a class.
|
static <T> T |
newInstanceSimple(Class<T> _class)
Simply calls
Class.newInstance() and hides the exception handling boilerplate code. |
static <T> T[] |
replaceInArray(T[] array,
int index,
T value)
Shortcut helper method that replaces an item in an array and returns the array itself.
|
static void |
resetCaches() |
static Field |
solveField(Object o,
String fieldName)
Returns a field from the given object that goes by the name of
fieldName. |
static Class<?> |
widestNumberClass(Number... numbers)
Returns the smallest class that can hold all of the specified numbers.
|
public static void resetCaches()
@Nullable public static Class<?> locateClass(String className, boolean fullscan, ExternalClassLoader classLoader)
locateClass(String, ExternalClassLoader), using default cache.@Nullable public static Class<?> locateClass(String className, boolean fullscan, ExternalClassLoader classLoader, boolean useCache)
className - The name of the class to locate.fullscan - Whether a full scan through all available java packages is required.classLoader - Optional user-provided classloader.Class reference if found or null otherwise.@Nullable public static Class<?> locateClass(String fullClassName, ExternalClassLoader classLoader)
Class.forName(String).fullClassName - The Class that needs to be found.classLoader - Optional user-provided classloader.Class object found from cache or VM.@Nonnull public static <T> T newInstanceSimple(Class<T> _class)
Class.newInstance() and hides the exception handling boilerplate code.T - Type used to parameterize the return instance._class - The datatype for which we need to create a new instance of.@Nullable public static <T> T invokeCompatibleMethod(Object context, Class<?> datatype, String identifier, Object... args) throws NoSuchMethodException, IllegalArgumentException, IllegalAccessException, InvocationTargetException
Method cache is being maintained to quickly
fetch heavily used methods. If not cached before and if a simple search (autoboxing and supertype casts) fails a more complex search is done
where all interfaces are searched for the method as well. If this fails as well, this method will try to autoconvert the types of the arguments
and find a matching signature that way.context - The object to call the method from (can be null).datatype - The class to find the method on.identifier - The name of the method to locate.args - A list of [non-formal] arguments.NoSuchMethodException - Thrown by findCompatibleMethod(Class, String, EnumSet, Class...).IllegalArgumentException - Thrown by Method.invoke(Object, Object...).IllegalAccessException - Thrown by Method.invoke(Object, Object...).InvocationTargetException - Thrown by Method.invoke(Object, Object...).@Nonnull public static <T> T invokeCompatibleConstructor(Class<T> datatype, Object... args) throws NoSuchMethodException, IllegalAccessException, InvocationTargetException, InstantiationException
Constructorusing invokeConstructor(Class, Class[], Object[])T - Used to parameterize the returned object so that the caller doesn't need to cast.datatype - The class to find the constructor for.args - A list of [non-formal] arguments.IllegalAccessException - Thrown by invokeConstructor(Class, Class[], Object[]).InvocationTargetException - Thrown by invokeConstructor(Class, Class[], Object[]).InstantiationException - Thrown by invokeConstructor(Class, Class[], Object[]).NoSuchMethodException - Thrown by invokeConstructor(Class, Class[], Object[]).Constructor.newInstance(Object[])@Nonnull public static <T> T invokeConstructor(Class<T> datatype, Class<?>[] signature, Object[] args) throws NoSuchMethodException, IllegalAccessException, InvocationTargetException, InstantiationException
Constructor, using a customized typelist. Avoids dynamically trying to find correct parameter type list. Can also
be used to force up/down casting (ie. passing a specific type of List into a generic type)T - Used to parameterize the returned object so that the caller doesn't need to cast.datatype - The class to find the constructor for.signature - The typelist used to find correct constructor.args - A list of [non-formal] arguments.IllegalAccessException - Thrown by Constructor.newInstance(Object...).InvocationTargetException - Thrown by Constructor.newInstance(Object...).InstantiationException - Thrown by Constructor.newInstance(Object...).NoSuchMethodException - Thrown by findCompatibleConstructor(Class, EnumSet, Class...).Constructor.newInstance(Object[])@Nonnull public static Class<?>[] collectTypes(Object[] objects)
NOTE: this method will never return primitive classes (such as double.class, as you can't put primitive values into an array of Objects (they will be autoboxes by the JVM).
objects - The array of objects to harvest classtypes from.@Nonnull public static <T> Constructor<T> findCompatibleConstructor(Class<T> datatype, EnumSet<JReflect.LookupMode> lookupMode, Class<?>... types) throws NoSuchMethodException
Constructor of a given type, with a given typelist, where types do not match due to formal types simple types.
This expanded version tries a simple call first and when it fails, it generates a list of type arrays with all possible (un)wraps of any type
in the original list possible, and combinations thereof.T - Used to parameterize the returned constructor.datatype - The class to get the constructor from.lookupMode - Flag indicating the search steps that need to be done.types - The list of types as specified by the user.NoSuchMethodException - Thrown when the Constructor could not be found on the data type, even after performing optional
conversions.@Nullable public static Method findSimpleCompatibleMethod(Class<?> datatype, String methodName, Class<?>... signature)
findCompatibleMethod(Class, String, EnumSet, Class...), using strict lookupmode (no autoboxing, casting etc.) and
optional signature parameters.datatype - The class to get the constructor from.methodName - The name of the method to retrieve from the class.signature - The list of types as specified by the user.null in case of a NoSuchMethodException exception.findCompatibleMethod(Class, String, EnumSet, Class...)@Nonnull public static Method findCompatibleMethod(Class<?> datatype, String methodName, EnumSet<JReflect.LookupMode> lookupMode, Class<?>... signature) throws NoSuchMethodException
getConstructor(), except for getting a Method of a classtype, using the name to indicate which method should be
located.datatype - The class to get the constructor from.methodName - The name of the method to retrieve from the class.lookupMode - Flag indicating the search steps that need to be done.signature - The list of types as specified by the user.NoSuchMethodException - Thrown when the Method could not be found on the data type, even after performing optional
conversions.@Nonnull public static Method getMethod(Class<?> datatype, String name, Class<?>... signature) throws NoSuchMethodException
Method using java reflect using a specific signature. This method will first search all
implemented interfaces for the method to avoid visibility problems.Iterator as implemented by the ArrayList. The Iterator is implemented as a
private innerclass and as such not accessible by java reflect (even though the implemented methods are declared public), unlike the
interface's definition.datatype - The class reference to locate the method on.name - The name of the method to find.signature - The signature the method should match.NoSuchMethodException - Thrown when the Method could not be found on the interfaces implemented by the given data type.Class.getMethod(String, Class[])@Nullable public static Class<?> autobox(Class<?> c)
c - The datatype to convert (autobox).@Nullable public static Field solveField(Object o, String fieldName)
fieldName. If o is a Class object, a static field will
be returned.o - The reference to the object to fetch the property value from.fieldName - The identifier or name of the member field/property.Field.@Nullable public static Object assignToField(Object o, String property, Object value) throws IllegalAccessException, NoSuchFieldException
id on the given object o. If a simple assignment fails, a common conversion will be
attempted.o - The object to find the field on.property - The name of the field we're assigning the value to.value - The value to assign to the field, may be converted to the field's type through common conversion.IllegalAccessException - Thrown by Field.set(Object, Object)NoSuchFieldException - Thrown if the Field could not be found, even after trying to convert the value to the target type.ValueConverter.convert(Object, Class)public static boolean isPackage(String name)
name - The string representing a list of packages.@Nonnull public static Class<?> widestNumberClass(Number... numbers)
numbers - The list with numbers that all should fit in the Number container.Number container that is just large enough for all specified numbers.@Nonnull public static Collection<String> collectProperties(Object subject)
Object.subject - The Object who's properties/fields need to be reflected.Object.@Nonnull public static Set<String> collectMethods(Object subject, boolean publicOnly)
Objectsubject - The Object who's methods need to be reflected.publicOnly - Indicates whether only public (albeit inherited) members should be returned. Else also private and protected methods will be
includedMethods.@Nonnull public static <T> T[] replaceInArray(T[] array, int index, T value)
T - The type of object that goes into the array.array - The array that needs an item replaced.index - The index at which the new value should be inserted.value - The value to insert at the specified index in the specified array.Copyright © 2018. All rights reserved.