Class XReflect
public final class XReflect extends Object
-
Constructor Summary
Constructors Constructor Description XReflect()
-
Method Summary
Modifier and Type Method Description static int
calculatePrimitivesLength(Field[] primFields)
static Field[]
collectInstanceFields(Class<?> objectClass)
static Field[]
collectInstanceFields(Class<?> objectClass, Predicate<? super Field> selector)
static Field[]
collectPrimitiveFieldsByByteSize(Field[] fields, int byteSize)
static <T, S extends T>
ScopyFields(T source, S target)
static <T, S extends T>
ScopyFields(T source, S target, Predicate<? super Field> fieldSelector)
static <T, S extends T>
ScopyFields(T source, S target, Predicate<? super Field> fieldSelector, CopyPredicate copySelector)
static <T> T
defaultInstantiate(Class<T> type)
static ClassLoader
defaultTypeResolvingClassLoader()
Local alias forClassLoader.getSystemClassLoader()
.static String
deriveFieldIdentifier(Field field)
static char
fieldIdentifierDelimiter()
static Field
getAnyField(Class<?> c, String name)
static Field
getAnyField(Class<?> c, Predicate<? super Field> predicate)
static Method
getAnyMethod(Class<?> c, String name)
static Method
getAnyMethod(Class<?> c, Predicate<? super Method> predicate)
static <T> Class<T>
getClass(T object)
*sighstatic Class<?>[]
getClassHierarchyInterfaces(Class<?> classClass)
static Class<?>
getDeclaredEnumClass(Class<?> c)
static Field
getDeclaredField(Class<?> c, String name)
static Field
getField(Class<?> c, String name)
static int
getField_int(Field f, Object obj)
static String
getFieldIdentifierClassName(String fieldIdentifier)
static int
getFieldIdentifierDelimiterIndex(String identifier)
static String
getFieldIdentifierFieldName(String fieldIdentifier)
static Object
getFieldValue(Field field, Object obj)
CallsField.get(Object)
and wraps the moronic abstraction-destroying checkedIllegalAccessException
with a properIllegalAccessRuntimeException
.static Field
getInstanceFieldOfType(Class<?> declaringType, Class<?> fieldType)
static Class<?>
getSuperClassNonNull(Class<?> c)
static boolean
hasEnumeratedTypeName(Class<?> type)
static boolean
implementsInterface(Class<?> c, Class<?> interfaceClass)
static boolean
isAbstract(Class<?> type)
static boolean
isAbstract(Method method)
static boolean
isActualClass(Class<?> type)
static boolean
isDeclaredEnum(Class<?> c)
static boolean
isDefaultVisible(Member field)
static boolean
isEnum(Class<?> c)
Utility method fixing the WRONGLY implementedClass.isEnum()
.static boolean
isFinal(Member field)
static boolean
isInstanceField(Field field)
static boolean
isInterfaceOfType(Class<?> interfaceClass, Class<?> implementedSuperInterface)
static boolean
isJavaUtilCollectionType(Class<?> type)
Checks if the passed type is equal to or a sub type ofCollection
orMap
.static boolean
isNotTransient(Field field)
static boolean
isOfAnyType(Class<?> subject, Class<?>... supertypes)
static boolean
isOfAnyType(Class<?> subject, Iterable<Class<?>> supertypes)
static boolean
isOfClassType(Class<?> c, Class<?> superclass)
static boolean
isPrimitive(Field field)
static boolean
isPrimitiveTypeName(String typeName)
static boolean
isPrivate(Member field)
static boolean
isProtected(Member field)
static boolean
isProxyClass(Class<?> c)
static boolean
isPublic(Member field)
static boolean
isReference(Field field)
static boolean
isStatic(Member field)
static boolean
isStaticFinal(Member field)
static boolean
isSubClassOf(Class<?> c, Class<?> superclass)
static boolean
isSubEnum(Class<?> c)
static boolean
isSynthetic(Member field)
static boolean
isTransient(Field field)
static boolean
isValidProxyClass(Class<?> c)
static <C extends Consumer<? super Method>>
CiterateAllClassMethods(Class<?> clazz, C logic)
static <C extends Consumer<? super Method>>
CiterateAllClassMethods(Class<?> clazz, Class<?> bound, C logic)
static <L extends Consumer<Field>>
LiterateDeclaredFieldsUpwards(Class<?> startingClass, Class<?> boundingClass, L logic)
Iterates over every declared field of all classes upwards starting at startingClassuntil class boundingClass is reached and executes the passedConsumer
on it.static <L extends Consumer<Field>>
LiterateDeclaredFieldsUpwards(Class<?> startingClass, L logic)
Alias foriterateDeclaredFieldsUpwards(startingClass, Object.class, logic)
.static Class<?>
iterativeResolveType(ClassLoader classLoader, String... typeNames)
Alias fortryIterativeResolveType(ClassLoader,String...)
with the following difference:
If none of the passed typeNames can be resolved, aClassNotFoundException
listing all passed typeNames is thrown.static Class<?>
iterativeResolveType(String... typeNames)
static char
nestedClassNameSeparator()
static Object
resolveEnumConstantInstance(Class<?> type, int ordinal)
static <T> T
resolveEnumConstantInstanceTyped(Class<T> type, int ordinal)
static Class<?>
resolveType(String typeName)
static Class<?>
resolveType(String typeName, ClassLoader classLoader)
Resolves the passed type name to a runtime type (instance of typeClass
).static Class<?>
resolveTypeForName(String typeName)
UsesClass.forName(String)
which uses the calling class'sClassLoader
.static Field
setAccessible(Class<?> actualClass, Field field)
static Field
setAccessible(Field field)
static void
setFieldValue(Field field, Object obj, Object value)
CallsField.set(Object,Object)
and wraps the moronic abstraction-destroying checkedIllegalAccessException
with a properIllegalAccessRuntimeException
.static String
toFieldName(Field field)
static String
toFullQualifiedFieldName(Class<?> actualClass, Field field)
static String
toFullQualifiedFieldName(Class<?> c, String fieldName)
static Field
tryGetDeclaredField(Class<?> declaringClass, String fieldName)
static Class<?>
tryIterativeResolveType(ClassLoader classLoader, String... typeNames)
This methods attempts to resolve the passed typeNames toClass
instances using#resolveType(ClassLoader,String)
one by one.static Class<?>
tryIterativeResolveType(String... typeNames)
static Class<?>
tryResolvePrimitiveType(String className)
static Class<?>
tryResolveType(String className)
static Class<?>
tryResolveType(String className, ClassLoader classLoader)
CallsresolveType(String,ClassLoader)
, but suppresses anyClassNotFoundException
and returnsnull
instead.static String
typename_enum()
static <A> Class<A>
validateArrayType(Class<A> arrayType)
static <T, S extends T>
voidvalidateFamiliarClass(T superClassInstance, S sameOrSubClassInstance)
Checks ifsuperClassInstance.getClass().isAssignableFrom(sameOrSubClassInstance.getClass())
static <A> Class<A>
validateInterfaceType(Class<A> type)
static <T> Class<T>
validateIsEnum(Class<T> type)
static <A> Class<A>
validateNonArrayType(Class<A> type)
static <A> Class<A>
validateNonInterfaceType(Class<A> type)
static <A> Class<A>
validateNonPrimitiveType(Class<A> primitiveType)
static <A> Class<A>
validatePrimitiveType(Class<A> primitiveType)
static <T> Instantiator<T>
WrapDefaultConstructor(Class<T> type)
-
Constructor Details
-
XReflect
public XReflect()
-
-
Method Details
-
defaultInstantiate
public static final <T> T defaultInstantiate(Class<T> type) throws NoSuchMethodRuntimeException, InstantiationRuntimeException -
setAccessible
-
setAccessible
- Throws:
SecurityException
-
isInstanceField
-
toFieldName
-
isInterfaceOfType
-
implementsInterface
-
getClassHierarchyInterfaces
-
isOfClassType
-
isSubClassOf
-
isActualClass
-
isEnum
Utility method fixing the WRONGLY implementedClass.isEnum()
.Their description is weird ("if this class was declared as an enum in the source code") and the implemented behavior is dangerous and useless to identify all classes of instances that are enums.
For enum anonymous inner class instances (writing { ... } behind an enum constant),
Class.isEnum()
returns false on the generated type. That is a bug since the type is still an enum, a sub class ofEnum
. So the correct way of testing a class for being an enum is usingjava.lang.Enum.class.isAssignableFrom(...)
. This method does that. -
isDeclaredEnum
-
isSubEnum
-
getDeclaredEnumClass
-
resolveEnumConstantInstance
-
resolveEnumConstantInstanceTyped
-
validateIsEnum
-
iterateDeclaredFieldsUpwards
public static final <L extends Consumer<Field>> L iterateDeclaredFieldsUpwards(Class<?> startingClass, L logic)Alias foriterateDeclaredFieldsUpwards(startingClass, Object.class, logic)
.- Type Parameters:
L
- The logic's contextual type.- Parameters:
startingClass
- the class whose fields shall be iterated.logic
- theConsumer
to be executed on each field.- Returns:
- the passed logic.
-
iterateDeclaredFieldsUpwards
public static final <L extends Consumer<Field>> L iterateDeclaredFieldsUpwards(Class<?> startingClass, Class<?> boundingClass, L logic)Iterates over every declared field of all classes upwards starting at startingClassuntil class boundingClass is reached and executes the passedConsumer
on it.The declared fields of each class are iterated in reverse order (from index
Class.getDeclaredFields()
.length - 1
to index0
).This method is useful to maintain the natural declaration order of the fields, iterating from the last declared field of the lowest class (the passed class itself) to the first declared field of the highest class declaring a field.
- Type Parameters:
L
- The logic's contextual type.- Parameters:
startingClass
- the class whose fields shall be iterated.boundingClass
- the class in the hierarchy at which to stop iterating, exclusive bound.logic
- theConsumer
to be executed on each field.- Returns:
- the passed logic.
-
getDeclaredField
public static final Field getDeclaredField(Class<?> c, String name) throws NoSuchFieldRuntimeException- Throws:
NoSuchFieldRuntimeException
-
getField
- Throws:
NoSuchFieldRuntimeException
-
getAnyField
- Throws:
NoSuchFieldRuntimeException
-
getAnyField
public static final Field getAnyField(Class<?> c, Predicate<? super Field> predicate) throws NoSuchFieldRuntimeException- Throws:
NoSuchFieldRuntimeException
-
getInstanceFieldOfType
public static final Field getInstanceFieldOfType(Class<?> declaringType, Class<?> fieldType) throws NoSuchFieldRuntimeException- Throws:
NoSuchFieldRuntimeException
-
getAnyMethod
public static final Method getAnyMethod(Class<?> c, String name) throws NoSuchMethodRuntimeException- Throws:
NoSuchMethodRuntimeException
-
getAnyMethod
public static final Method getAnyMethod(Class<?> c, Predicate<? super Method> predicate) throws NoSuchMethodRuntimeException- Throws:
NoSuchMethodRuntimeException
-
iterateAllClassMethods
-
iterateAllClassMethods
-
isFinal
-
isStatic
-
isSynthetic
-
isStaticFinal
-
isPrimitive
-
isReference
-
isTransient
-
isNotTransient
-
isPrivate
-
isProtected
-
isPublic
-
isDefaultVisible
-
isAbstract
-
isAbstract
-
getFieldValue
CallsField.get(Object)
and wraps the moronic abstraction-destroying checkedIllegalAccessException
with a properIllegalAccessRuntimeException
.- Parameters:
field
- the field from which the value shall be extracted.obj
- object from which the represented field's value is to be extracted- Returns:
- the value of the represented field in object
obj
; primitive values are wrapped in an appropriate object before being returned
-
setFieldValue
CallsField.set(Object,Object)
and wraps the moronic abstraction-destroying checkedIllegalAccessException
with a properIllegalAccessRuntimeException
.- Parameters:
field
- the field to be modifiedobj
- the object whose field should be modifiedvalue
- the new value for the field ofobj
being modified
-
getField_int
- Throws:
IllegalAccessRuntimeException
-
resolveType
public static final Class<?> resolveType(String typeName, ClassLoader classLoader) throws LinkageError, ExceptionInInitializerError, ClassNotFoundExceptionResolves the passed type name to a runtime type (instance of typeClass
). In contrary to JDK's type resolving mechanisms, this method resolves primitive type names, as well.Note on naming:
1.) Looking up a runtime type instance for a type name string is best described as "resolving" the type.
2.) The things that are resolved are TYPES (classes, interfaces, arrays and in later Java versions enums and annotations), not just classes. That the java inventors seemingly didn't understand their own type system and just called everything "Class" on the API-level,* even interfaces, is just an error that should be repeated as less as possible.- Parameters:
typeName
- the type name to be resolved, primitive name or full qualified type name.- Returns:
- the resolved type instance (of type
Class
) - Throws:
LinkageError
- seeClass.forName(String)
ExceptionInInitializerError
- seeClass.forName(String)
ClassNotFoundException
- seeClass.forName(String)
-
resolveTypeForName
public static final Class<?> resolveTypeForName(String typeName) throws LinkageError, ExceptionInInitializerError, ClassNotFoundExceptionUsesClass.forName(String)
which uses the calling class'sClassLoader
.- Parameters:
typeName
-- Returns:
- Throws:
LinkageError
ExceptionInInitializerError
ClassNotFoundException
-
tryResolveType
CallsresolveType(String,ClassLoader)
, but suppresses anyClassNotFoundException
and returnsnull
instead. This is useful if the passed class name is only potentially resolvable at runtime and is still valid if not. Example: resolving a old type dictionary as far as possible and marking the not resolvable types as unresolvable.- Parameters:
className
-- Returns:
- the
Class
instance representing the passed class name ornull
if unresolevable.
-
iterativeResolveType
public static final Class<?> iterativeResolveType(ClassLoader classLoader, String... typeNames) throws ClassNotFoundExceptionAlias fortryIterativeResolveType(ClassLoader,String...)
with the following difference:
If none of the passed typeNames can be resolved, aClassNotFoundException
listing all passed typeNames is thrown.- Parameters:
typeNames
- the full qualified type names to be attempted to be resolved one by one.- Returns:
- the first successfully resolved
Class
instance. - Throws:
ClassNotFoundException
- if none of the passed typeNames could have been resolved.- See Also:
#tryIterativeResolveType(ClassLoader,String)
-
tryIterativeResolveType
This methods attempts to resolve the passed typeNames toClass
instances using#resolveType(ClassLoader,String)
one by one. TheClass
instance of the first successful attempt is returned. If none of the passed typeNames can be resolved, null is returned. SeeiterativeResolveType(ClassLoader,String...)
for an exception-throwing version.Note:
While it is generally a bad idea to just use a trial and error approach until something works, a logic like this is required to resolve types whose packages changes accross different versions of a library. If the different full qualified class names are known, they can be used in an iterative attempt to resolve the class, hence avoiding hard dependencies to certain library versions in the using code by moving type names from imports at compile time to dynamic class resolving at runtime.
However, this approach has its limits, of course. If too much changes (field names, method names, parameters, behavior) the dynamic strategy results in chaos as the compiler gets more and more circumvented and more and more source code is transformed into contextless plain strings.
Therefore, when in doubt, it is preferable to stick to the general notion of this method being a "bad idea" and finding a more reliable solution.- Parameters:
typeNames
- the full qualified type names to be attempted to be resolved one by one.- Returns:
- the first successfully resolved
Class
instance or null - See Also:
#resolveType(ClassLoader,String)
-
defaultTypeResolvingClassLoader
Local alias forClassLoader.getSystemClassLoader()
.- Returns:
- the system class loader.
-
resolveType
public static final Class<?> resolveType(String typeName) throws LinkageError, ExceptionInInitializerError, ClassNotFoundExceptionCallsresolveType(String,ClassLoader)
withdefaultTypeResolvingClassLoader()
. Make sure this is a suitableClassLoader
when using this method.- Parameters:
typeName
-- Returns:
- Throws:
LinkageError
ExceptionInInitializerError
ClassNotFoundException
-
tryResolveType
CallstryResolveType(String,ClassLoader)
withdefaultTypeResolvingClassLoader()
. Make sure this is a suitableClassLoader
when using this method.- Parameters:
className
-- Returns:
-
iterativeResolveType
public static final Class<?> iterativeResolveType(String... typeNames) throws ClassNotFoundExceptionCallsiterativeResolveType(ClassLoader,String...)
withdefaultTypeResolvingClassLoader()
. Make sure this is a suitableClassLoader
when using this method.- Parameters:
typeName
-- Returns:
- Throws:
ClassNotFoundException
-
tryIterativeResolveType
-
tryGetDeclaredField
-
tryResolvePrimitiveType
-
isPrimitiveTypeName
-
isOfAnyType
-
isOfAnyType
-
getClass
*sigh- Parameters:
object
-
-
fieldIdentifierDelimiter
public static char fieldIdentifierDelimiter() -
typename_enum
-
nestedClassNameSeparator
public static char nestedClassNameSeparator() -
toFullQualifiedFieldName
-
deriveFieldIdentifier
-
toFullQualifiedFieldName
-
getFieldIdentifierDelimiterIndex
-
getFieldIdentifierClassName
-
getFieldIdentifierFieldName
-
validateInterfaceType
-
validateNonInterfaceType
-
validateNonArrayType
-
validateArrayType
-
validatePrimitiveType
-
validateNonPrimitiveType
-
WrapDefaultConstructor
public static <T> Instantiator<T> WrapDefaultConstructor(Class<T> type) throws NoSuchMethodRuntimeException- Throws:
NoSuchMethodRuntimeException
-
isJavaUtilCollectionType
Checks if the passed type is equal to or a sub type ofCollection
orMap
.Sad that such a method is necessary in the first place, but here we are.
(SeeXMap
for an example on how to do it correctly.)- Parameters:
type
- the type to be checked.- Returns:
- whether or not the passed type is a java.util collection "in the broader sense".
- See Also:
Collection
,Map
-
hasEnumeratedTypeName
-
isProxyClass
-
isValidProxyClass
-
collectPrimitiveFieldsByByteSize
-
collectInstanceFields
-
collectInstanceFields
-
calculatePrimitivesLength
-
copyFields
public static <T, S extends T> S copyFields(T source, S target) -
copyFields
-
copyFields
public static <T, S extends T> S copyFields(T source, S target, Predicate<? super Field> fieldSelector, CopyPredicate copySelector) -
validateFamiliarClass
public static <T, S extends T> void validateFamiliarClass(T superClassInstance, S sameOrSubClassInstance)Checks ifsuperClassInstance.getClass().isAssignableFrom(sameOrSubClassInstance.getClass())
- Type Parameters:
T
-S
-- Parameters:
superClassInstance
-sameOrSubClassInstance
-
-
getSuperClassNonNull
-