Reflection utilities combines both Java's reflective and annotation inspection APIs on a single API. Java's own reflective API is pretty powerful but the annotation inspection API is dispersed through several classes making it hard to use. To surmont this shortcomming Reflection utilities aggregates functionalities from both domains. On essence, Java's annotation inspection mechanisms are part of the reflective API so this was API was named after the reflective API.
Please refer to the Reflection utilities Javadoc for the complete API specification.
There several methods to inspect the annotations of the different annotation targets. Each of these methods is overloaded to work both with class names or class objects arguments. Reflection utilities offers methods to find type, method and attribute annotations and also a method to get all the annotations on a given class (mind the overloading). The methods names will be detailed below and since they all work in the same fashion only an example will be presented. All the methods return a list of Annotation objects.
To fetch all the type, method and attribute annotations on a given class use the following methods:
To fetch all the attribute annotations on a given class use the following methods:
To fetch all the method annotations on a given class use the following methods:
To fetch all the type annotations on a given class use the following methods:
To find if a class is annotated with a given annotation use the isAnnotatedWith(String, String) method. The methods arguments are the class's and annotation's FQNs. Returns TRUE if the class contains the given annotations and FALSE otherwise.
Note: this method searches for type, method and attribute annotations!
To find out the target scopes of a given annotation use the getAnnotationTarget(Annotation) method. The method's must be passed an annotation and it returns list with the ElementType valid annotation scopes.
... try { List<Annotation> annotations = ReflectionUtils.getAllAnnotationsForClass("pt.digitalis.utils.inspection.MockUpClass"); for (Annotation annotation : annotations) System.out.println(annotation.annotationType().getCanonicalName()); } catch (ResourceNotFoundException resourceNotFoundException) { // Exception-handling code } ...
Assuming MockUpClass has been annotated with a type annotation named TypeAnnotation, a method annotation named MethodAnnotation and an attribute annotation named AttributeAnnotation the code above would produce the following output:
pt.digitalis.utils.inspection.TypeAnnotation pt.digitalis.utils.inspection.MethodAnnotation pt.digitalis.utils.inspection.AttributeAnnotation
Please note that the annotations retention policy must be RUNTIME.
To access a class's attributes Reflection utilities offers four methods:
The first two methods return a list with all the class's attributes (of the type Field) and the last two return the specified attribute.
There are three kinds of method inspection operations: get all mehods of a given class, get a specific method of a given class and finding out if a given method is an inspector. An inspector is defined as a nullary (zero-argument) function whose name starts with "get" and whose return is different from 'void'.
Here's the method inspecting API:
The first two methods return a list with all the class's methods (of the type Method), the following two return the specified method and the last one returns a boolean, as specificied on the method's Javadoc.
Reflection utilities offers three ways to instantiate an object: from a class object, from a class constructor and from the class's FQN.
Since the usage of this feature is non-trivial, examples will be presented for the three ways.
... Class mockupClass = MockUpClass.class; try { MockUpClass mockupObject = (MockUpClass) ReflectionUtils.instantiateObjectFromClass(mockupClass); // More code here } catch (AuxiliaryOperationException e) { // Exception-handling code... } ...
Note the need for an explicit cast to the target object type.
... Class[] arguments = null; try { Constructor<MockUpClass> constructor = (Constructor<MockUpClass>) MockUpClass.class.getConstructor(arguments); MockUpClass mockupObject = (MockUpClass) ReflectionUtils.instantiateObjectFromClass(constructor, (Object[]) arguments); } catch (Exception e) { // Exception-handling code... } ...
Note the need for an explicit cast to the target object type.
... try { MockUpClass mockupObject = (MockUpClass) ReflectionUtils.instantiateObjectFromClass("pt.digitalis.utils.inspection.MockUpClass"); } catch (AuxiliaryOperationException e) { // Exception-handling code... } ...
Note the need for an explicit cast to the target object type.
To invoke a method on an object, Reflection utilities offers invokeMethod(Method, Class, Object[]...). The first argument is an object that represents the method to invoke, the second argument is target class and the third is and array of Objects that will be fed as arguments to the called method. The last argument is a vararg. More on this subject here. The method returns an object that matches the called method's return type and whose content is the called method return.
There's also an overloaded version of the method that accepts String-type parameters for the method's and target object names. See the method's Javadoc.
... Object[] arguments = null; try { Method method = ReflectionUtils.getMethod(MockUpClass.class, "getter"); Object result = ReflectionUtils.invokeMethod(method, MockUpClass.class, arguments); // More code here } catch(Exception exception) { // Exception-handling code... } ...