Class XReflect
- java.lang.Object
-
- one.microstream.reflect.XReflect
-
public final class XReflect extends Object
Provides additional generic util methods for working with java reflection.
-
-
Constructor Summary
Constructors Constructor Description XReflect()
-
Method Summary
Modifier and Type Method Description 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<? extends 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 boolean
hasEnumeratedTypeName(Class<?> type)
static boolean
implementsInterface(Class<?> c, Class<?> interfaceClass)
static boolean
isAbstract(Class<?> type)
static boolean
isAbstract(Method method)
static boolean
isDeclaredEnum(Class<?> c)
static boolean
isDefaultVisible(Field field)
static boolean
isEnum(Class<?> c)
Utility method fixing the WRONGLY implementedClass.isEnum()
.static boolean
isFinal(Field 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(Field field)
static boolean
isProtected(Field field)
static boolean
isProxyClass(Class<?> c)
static boolean
isPublic(Field field)
static boolean
isReference(Field field)
static boolean
isStatic(Field field)
static boolean
isStaticFinal(Field field)
static boolean
isSubClassOf(Class<?> c, Class<?> superclass)
static boolean
isSubEnum(Class<?> c)
static boolean
isSynthetic(Field 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(String... typeNames)
Alias fortryIterativeResolveType(String...)
with the following difference:
If none of the passed typeNames can be resolved, aClassNotFoundException
listing all passed typeNames is thrown.static char
nestedClassNameSeparator()
static Object
resolveEnumConstantInstance(Class<?> type, int ordinal)
static <T> T
resolveEnumConstantInstanceTyped(Class<T> type, int ordinal)
static Class<?>
resolveType(String typeName)
Resolves the passed type name to a runtime type (instance of typeClass
).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<?> c, String fieldName)
static Field
tryGetDeclaredField(Class<?> declaringClass, String fieldName)
static Class<?>
tryIterativeResolveType(String... typeNames)
This methods attempts to resolve the passed typeNames toClass
instances usingClass.forName(String)
one by one.static Class<?>
tryResolvePrimitiveType(String className)
static Class<?>
tryResolveType(String className)
static String
typename_enum()
static <A> Class<A>
validateArrayType(Class<A> arrayType)
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)
-
-
-
Method Detail
-
isInstanceField
public static final boolean isInstanceField(Field field)
-
isInterfaceOfType
public static final boolean isInterfaceOfType(Class<?> interfaceClass, Class<?> implementedSuperInterface)
-
implementsInterface
public static final boolean implementsInterface(Class<?> c, Class<?> interfaceClass)
-
getClassHierarchyInterfaces
public static final Class<?>[] getClassHierarchyInterfaces(Class<?> classClass)
-
isEnum
public static boolean isEnum(Class<?> c)
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
public static boolean isDeclaredEnum(Class<?> c)
-
isSubEnum
public static boolean isSubEnum(Class<?> c)
-
resolveEnumConstantInstance
public static Object resolveEnumConstantInstance(Class<?> type, int ordinal)
-
resolveEnumConstantInstanceTyped
public static <T> T resolveEnumConstantInstanceTyped(Class<T> type, int ordinal)
-
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
public static final Field getField(Class<?> c, String name) throws NoSuchFieldRuntimeException
- Throws:
NoSuchFieldRuntimeException
-
getAnyField
public static final Field getAnyField(Class<?> c, String name) throws NoSuchFieldRuntimeException
- 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
public static final <C extends Consumer<? super Method>> C iterateAllClassMethods(Class<?> clazz, C logic)
-
iterateAllClassMethods
public static final <C extends Consumer<? super Method>> C iterateAllClassMethods(Class<?> clazz, Class<?> bound, C logic)
-
isFinal
public static final boolean isFinal(Field field)
-
isStatic
public static final boolean isStatic(Field field)
-
isSynthetic
public static final boolean isSynthetic(Field field)
-
isStaticFinal
public static final boolean isStaticFinal(Field field)
-
isPrimitive
public static final boolean isPrimitive(Field field)
-
isReference
public static final boolean isReference(Field field)
-
isTransient
public static final boolean isTransient(Field field)
-
isNotTransient
public static final boolean isNotTransient(Field field)
-
isPrivate
public static final boolean isPrivate(Field field)
-
isProtected
public static final boolean isProtected(Field field)
-
isPublic
public static final boolean isPublic(Field field)
-
isDefaultVisible
public static final boolean isDefaultVisible(Field field)
-
isAbstract
public static final boolean isAbstract(Class<?> type)
-
isAbstract
public static final boolean isAbstract(Method method)
-
getFieldValue
public static final Object getFieldValue(Field field, Object obj)
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
public static final void setFieldValue(Field field, Object obj, Object value)
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
public static int getField_int(Field f, Object obj) throws IllegalAccessRuntimeException
- Throws:
IllegalAccessRuntimeException
-
resolveType
public static final Class<?> resolveType(String typeName) throws LinkageError, ExceptionInInitializerError, ClassNotFoundException
Resolves the passed type name to a runtime type (instance of typeClass
). In contrary toClass.forName(String)
, this method can resolve 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.
In conclusion, the proper naming for the action executed by this method (meaning a verb) is "resolveType" and not a dilettantish "forName" as inClass.forName(String)
.- 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)
-
tryResolveType
public static final Class<?> tryResolveType(String className)
CallsresolveType(String)
, 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(String... typeNames) throws ClassNotFoundException
Alias fortryIterativeResolveType(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:
Class.forName(String)
-
tryIterativeResolveType
public static final Class<?> tryIterativeResolveType(String... typeNames)
This methods attempts to resolve the passed typeNames toClass
instances usingClass.forName(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(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:
Class.forName(String)
-
tryGetDeclaredField
public static final Field tryGetDeclaredField(Class<?> declaringClass, String fieldName)
-
isPrimitiveTypeName
public static boolean isPrimitiveTypeName(String typeName)
-
isOfAnyType
public static final boolean isOfAnyType(Class<?> subject, Iterable<Class<?>> supertypes)
-
getClass
public static <T> Class<? extends T> getClass(T object)
*sigh- Parameters:
object
-
-
fieldIdentifierDelimiter
public static char fieldIdentifierDelimiter()
-
typename_enum
public static String typename_enum()
-
nestedClassNameSeparator
public static char nestedClassNameSeparator()
-
toFullQualifiedFieldName
public static String toFullQualifiedFieldName(Class<?> c, String fieldName)
-
getFieldIdentifierDelimiterIndex
public static int getFieldIdentifierDelimiterIndex(String identifier)
-
getFieldIdentifierClassName
public static String getFieldIdentifierClassName(String fieldIdentifier)
-
getFieldIdentifierFieldName
public static String getFieldIdentifierFieldName(String fieldIdentifier)
-
validateNonPrimitiveType
public static <A> Class<A> validateNonPrimitiveType(Class<A> primitiveType)
-
WrapDefaultConstructor
public static <T> Instantiator<T> WrapDefaultConstructor(Class<T> type) throws NoSuchMethodRuntimeException
- Throws:
NoSuchMethodRuntimeException
-
isJavaUtilCollectionType
public static boolean isJavaUtilCollectionType(Class<?> type)
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
public static boolean hasEnumeratedTypeName(Class<?> type)
-
isProxyClass
public static boolean isProxyClass(Class<?> c)
-
isValidProxyClass
public static boolean isValidProxyClass(Class<?> c)
-
-