Package com.cedarsoftware.util
Class ReflectionUtils
- java.lang.Object
-
- com.cedarsoftware.util.ReflectionUtils
-
public final class ReflectionUtils extends Object
Utilities to simplify writing reflective code as well as improve performance of reflective operations like method and annotation lookups.- Author:
- John DeRegnaucourt ([email protected])
Copyright (c) Cedar Software LLC
Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.
-
-
Method Summary
All Methods Static Methods Concrete Methods Modifier and Type Method Description static Object
call(Object bean, Method method, Object... args)
Make reflective method calls without having to handle two checked exceptions (IllegalAccessException and InvocationTargetException).static Object
call(Object bean, String methodName, Object... args)
Make a reflective method call in one step.static <T extends Annotation>
TgetClassAnnotation(Class<?> classToCheck, Class<T> annoClass)
Determine if the passed in class (classToCheck) has the annotation (annoClass) on itself, any of its super classes, any of it's interfaces, or any of it's super interfaces.protected static String
getClassLoaderName(Class<?> c)
static String
getClassName(Object o)
Return the name of the class on the object, or "null" if the object is null.static String
getClassNameFromByteCode(byte[] byteCode)
Given a byte[] of a Java .class file (compiled Java), this code will retrieve the class name from those bytes.static Constructor<?>
getConstructor(Class<?> clazz, Class<?>... parameterTypes)
static void
getDeclaredFields(Class<?> c, Collection<Field> fields)
Get all non static, non transient, fields of the passed in class, including private fields.static Map<String,Field>
getDeepDeclaredFieldMap(Class<?> c)
Return all Fields from a class (including inherited), mapped by String field name to java.lang.reflect.Field.static Collection<Field>
getDeepDeclaredFields(Class<?> c)
Get all non static, non transient, fields of the passed in class, including private fields.static Method
getMethod(Class<?> c, String methodName, Class<?>... types)
Fetch a public method reflectively by name with argument types.static Method
getMethod(Object bean, String methodName, int argCount)
Fetch the named method from the passed in Object instance.static <T extends Annotation>
TgetMethodAnnotation(Method method, Class<T> annoClass)
static Method
getNonOverloadedMethod(Class clazz, String methodName)
Fetch the named method from the passed in Class.
-
-
-
Method Detail
-
getClassAnnotation
public static <T extends Annotation> T getClassAnnotation(Class<?> classToCheck, Class<T> annoClass)
Determine if the passed in class (classToCheck) has the annotation (annoClass) on itself, any of its super classes, any of it's interfaces, or any of it's super interfaces. This is a exhaustive check throughout the complete inheritance hierarchy.- Returns:
- the Annotation if found, null otherwise.
-
getMethodAnnotation
public static <T extends Annotation> T getMethodAnnotation(Method method, Class<T> annoClass)
-
getMethod
public static Method getMethod(Class<?> c, String methodName, Class<?>... types)
Fetch a public method reflectively by name with argument types. This method caches the lookup, so that subsequent calls are significantly faster. The method can be on an inherited class of the passed in [starting] Class.- Parameters:
c
- Class on which method is to be found.methodName
- String name of method to find.types
- Argument types for the method (null is used for no argument methods).- Returns:
- Method located, or null if not found.
-
getDeepDeclaredFields
public static Collection<Field> getDeepDeclaredFields(Class<?> c)
Get all non static, non transient, fields of the passed in class, including private fields. Note, the special this$ field is also not returned. The result is cached in a static ConcurrentHashMap to benefit execution performance.- Parameters:
c
- Class instance- Returns:
- Collection of only the fields in the passed in class that would need further processing (reference fields). This makes field traversal on a class faster as it does not need to continually process known fields like primitives.
-
getDeclaredFields
public static void getDeclaredFields(Class<?> c, Collection<Field> fields)
Get all non static, non transient, fields of the passed in class, including private fields. Note, the special this$ field is also not returned. The resulting fields are stored in a Collection.- Parameters:
c
- Class instance that would need further processing (reference fields). This makes field traversal on a class faster as it does not need to continually process known fields like primitives.
-
getDeepDeclaredFieldMap
public static Map<String,Field> getDeepDeclaredFieldMap(Class<?> c)
Return all Fields from a class (including inherited), mapped by String field name to java.lang.reflect.Field.- Parameters:
c
- Class whose fields are being fetched.- Returns:
- Map of all fields on the Class, keyed by String field name to java.lang.reflect.Field.
-
call
public static Object call(Object bean, Method method, Object... args)
Make reflective method calls without having to handle two checked exceptions (IllegalAccessException and InvocationTargetException). These exceptions are caught and rethrown as RuntimeExceptions, with the original exception passed (nested) on.- Parameters:
bean
- Object (instance) on which to call method.method
- Method instance from target object [easily obtained by calling ReflectionUtils.getMethod()].args
- Arguments to pass to method.- Returns:
- Object Value from reflectively called method.
-
call
public static Object call(Object bean, String methodName, Object... args)
Make a reflective method call in one step. This approach does not support calling two different methods with the same argument count, since it caches methods internally by "className.methodName|argCount". For example, if you had a class with two methods, foo(int, String) and foo(String, String), you cannot use this method. However, this method would support calling foo(int), foo(int, String), foo(int, String, Object), etc. Internally, it is caching the reflective method lookups as mentioned earlier for speed, using argument count as part of the key (not all argument types). Ideally, use the call(Object, Method, Object...args) method when possible, as it will support any method, and also provides caching. There are times, however, when all that is passed in (REST APIs) is argument values, and if some of those are null, you may have an ambiguous targeted method. With this approach, you can still call these methods, assuming the methods are not overloaded with the same number of arguments and differing types.- Parameters:
bean
- Object instance on which to call method.methodName
- String name of method to call.args
- Arguments to pass.- Returns:
- Object value returned from the reflectively invoked method.
-
getMethod
public static Method getMethod(Object bean, String methodName, int argCount)
Fetch the named method from the passed in Object instance. This method caches found methods, so it should be used instead of reflectively searching for the method every time. Ideally, use the other getMethod() API that takes an additional argument, Class[] of argument types (most desirable). This is to better support overloaded methods. Sometimes, you only have the argument values, and if they can be null, you cannot call the getMethod() API that take argument Class types.- Parameters:
bean
- Object on which the named method will be found.methodName
- String name of method to be located on the controller.argCount
- int number of arguments. This is used as part of the cache key to allow for duplicate method names as long as the argument list length is different.- Throws:
IllegalArgumentException
-
getConstructor
public static Constructor<?> getConstructor(Class<?> clazz, Class<?>... parameterTypes)
-
getNonOverloadedMethod
public static Method getNonOverloadedMethod(Class clazz, String methodName)
Fetch the named method from the passed in Class. This method caches found methods, so it should be used instead of reflectively searching for the method every time. This method expects the desired method name to not be overloaded.- Parameters:
clazz
- Class that contains the desired method.methodName
- String name of method to be located on the controller.- Returns:
- Method instance found on the passed in class, or an IllegalArgumentException is thrown.
- Throws:
IllegalArgumentException
-
getClassName
public static String getClassName(Object o)
Return the name of the class on the object, or "null" if the object is null.- Parameters:
o
- Object to get the class name.- Returns:
- String name of the class or "null"
-
getClassNameFromByteCode
public static String getClassNameFromByteCode(byte[] byteCode) throws Exception
Given a byte[] of a Java .class file (compiled Java), this code will retrieve the class name from those bytes.- Parameters:
byteCode
- byte[] of compiled byte code.- Returns:
- String name of class
- Throws:
Exception
- potential io exceptions can happen
-
-