Evaluating Software Design Patterns
— the "Gang of Four" patterns implemented in Java 6

dk.rode.thesis.meta.reflect
Class Reflection

java.lang.Object
  extended by dk.rode.thesis.meta.reflect.Reflection

public class Reflection
extends Object

Various reflection functionality.

Implementation notes:
Though all methods are declared static, instances of this class cannot be created, and hence it is in effect an application of the Singleton pattern.

Author:
Gunni Rode / rode.dk

Constructor Summary
private Reflection()
          Private off-limit constructor.
 
Method Summary
static Class<?> forName(CharSequence className)
          Returns the Class object associated with the class or interface with the name supplied as className.
static Set<Class<?>> getAssignableTo(Class<?> clazz)
          Returns an ordered set of the classes and/or interfaces the Class supplied as clazz can be assigned to.
static
<C extends Collection<Class<?>>>
C
getAssignableTo(Class<?> clazz, C classes)
          Returns a collection of the classes and/or interfaces the Class supplied as clazz can be assigned to.
static Class<?> getCallerClass()
          Returns the caller class of the calling context of the immediate calling context that invoked this method.
static Class<?> getClass(Class<?> clazz)
          Returns the first reachable named class or interface that can identify clazz.
static Constructor<?> getConstructor(Class<?> clazz, Class<?>... parameterTypes)
          Returns the constructor declared in the class supplied as clazz accepting the formal parameter types supplied as parameterTypes, ignoring primitive types.
static
<A extends Annotation>
Constructor<?>[]
getConstructors(Class<?> clazz, Class<A> annotation)
          Returns the constructors declared in the class supplied as clazz annotated with the annotation type supplied as annotation.
static
<T> Constructor<T>
getCopyConstructor(Class<T> clazz)
          Returns the copy constructor declared in clazz, if any.
static List<Field> getFields(Class<?> clazz)
          Returns all declared fields in clazz, or in a super-class or implemented interface.
static Set<Class<?>> getInterfaces(Class<?> clazz)
          Returns an ordered set of the interfaces the Class supplied as clazz can be assigned to, including interfaces implemented by super-classes of clazz.
static
<C extends Collection<Class<?>>>
C
getInterfaces(Class<?> clazz, C interfaces)
          Returns an ordered set of the interfaces the Class supplied as clazz can be assigned to, including interfaces implemented by super-classes of clazz.
static Method getMethod(Class<?> clazz, String name, Class<?>... parameterTypes)
          Returns the method with the name supplied as name that is declared in the class supplied as clazz accepting the formal parameter types supplied as parameterTypes, ignoring primitive types.
static List<Method> getMethods(Class<?> clazz)
          Returns all declared methods in clazz, or in a super-class or implemented interface.
static
<A extends Annotation>
Method[]
getMethods(Class<?> clazz, Class<A> annotation)
          Returns the methods declared in the class supplied as clazz annotated with the annotation type supplied as annotation.
static
<T> KeyValue<Class<? super T>,Class<? super T>>
getOverriding(Class<T> clazz, String name, Class<?>... types)
          Returns a (key,value) placeholder, where the key is the first super class of clazz, or clazz it self, declaring a non-abstract method with the name supplied as name and the formal parameter types supplied as types, providing it is accessible to clazz, and where the value is the first super class of that class declaring a similar method.
static
<T> List<Class<? super T>>
getSuperClasses(Class<T> clazz)
          Returns a list of all super-classes of clazz, excluding clazz, where the last index is always be Object.class.
static boolean hasAccess(Class<?> caller, Class<?> clazz)
          Checks whether or not caller can access clazz based on Java's visibility rules.
private static boolean hasAccess(Class<?> caller, Class<?> clazz, int modifiers)
          Checks whether or not the access modifiers supplied as modifiers allows caller to access to the owner of the modifiers declared in, or being, clazz.
static boolean hasAccess(Class<?> caller, Member member)
          Checks whether or not caller can access member based on Java's visibility rules.
static
<E extends AccessibleObject & Member>
Object
invoke(Object target, E member, Object... arguments)
          Returns the result of invoking the accessible member supplied as member.
static boolean isInstance(boolean nullValuesMatch, Class<?>[] types, Object... values)
          Returns true if each value in values is assignable to the corresponding type at the same index in types, respectively, false if not.
static boolean isInstance(Class<?>[] types, Object... values)
          Returns true if each value in values is assignable to the corresponding type at the same index in types, respectively, false if not.
static boolean isOverriding(Class<?> clazz, String name, Class<?>... types)
          Determines if a given accessible non-abstract method is overriding a similar method in a super class based on Java's visibility rules.
static boolean isSubClass(Class<?> clazz, Class<?> subClass)
          Returns true if and only if subClass is a sub-class of clazz, false otherwise.
static boolean isSuperClass(Class<?> clazz, Class<?> superClass)
          Returns true if and only if superClass is a super-class of clazz, false otherwise.
 
Methods inherited from class java.lang.Object
clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
 

Constructor Detail

Reflection

private Reflection()
Private off-limit constructor.

Method Detail

forName

public static final Class<?> forName(CharSequence className)
                              throws ClassNotFoundException
Returns the Class object associated with the class or interface with the name supplied as className.

Unlike the standard Class.forName(String) method, this method trims className before trying the load the class and it also handles primitive class names, e.g. int for Integer.TYPE etc.

Parameters:
className - The class name; cannot be null.
Returns:
The corresponding Class object; never null.
Throws:
NullPointerException - If className is null.
ClassNotFoundException - If no such class could be found.

getAssignableTo

public static final Set<Class<?>> getAssignableTo(Class<?> clazz)
Returns an ordered set of the classes and/or interfaces the Class supplied as clazz can be assigned to.

The contained classes either represent super-classes or implemented interfaces, including those implemented by super-classes.

The returned set lists the classes and interfaces in a depth first manner, i.e., super-classes precedes sub-classes. A given interface is only included once in the set, corresponding to the first time visited.

Parameters:
clazz - The class to fetch the assignable classes for; cannot be null.
Returns:
An ordered set of the assignable classes/interfaces; never null, and never empty (will always contain at least Object).
Throws:
NullPointerException - If clazz is null.

getAssignableTo

public static final <C extends Collection<Class<?>>> C getAssignableTo(Class<?> clazz,
                                                                       C classes)
Returns a collection of the classes and/or interfaces the Class supplied as clazz can be assigned to.

The contained classes either represent super-classes or implemented interfaces, including those implemented by super-classes.

The classes and interfaces are added to classes in a depth first manner, super-classes precedes sub-classes, but the collection type may or may not respect the insertion order. Furthermore, a given interface may be included more than one time in the returned collection, again depending on the type of collection.

Type Parameters:
C - The actual collection type to use.
Parameters:
clazz - The class to fetch the assignable classes for; cannot be null.
classes - The collection to add to classes and interfaces to; cannot be null.
Returns:
The classes collection; never null, and never empty (will always at least contain Object).
Throws:
NullPointerException - If either argument is null.

getCallerClass

public static final Class<?> getCallerClass()
Returns the caller class of the calling context of the immediate calling context that invoked this method.

The calling context can be either a static initialisation block, an instance initialisation block, a constructor, or a method. The caller class thus represents the class declaring such a member.

Example:

   ..
   public void foo {
     // Calling context
     this.bar();
   }
 
   public void bar {
     // Immediate calling context
     Class<?> callerClass = Reflection.getCallerClass(); // Represents the class of foo, *not* of bar
     .. 
   }
   ..
 

Returns:
The caller class of the calling context; never null.
See Also:
CallerClass, Caller

getClass

public static final Class<?> getClass(Class<?> clazz)
Returns the first reachable named class or interface that can identify clazz.

If clazz is null, then null is returned. If clazz is an anonymous class, the first non-anonymous super class is used or the first and only interface implemented.

Parameters:
clazz - The class; can be null.
Returns:
The class to use, or null.

getConstructor

public static final Constructor<?> getConstructor(Class<?> clazz,
                                                  Class<?>... parameterTypes)
                                           throws NoSuchMethodException
Returns the constructor declared in the class supplied as clazz accepting the formal parameter types supplied as parameterTypes, ignoring primitive types.

In case several constructors match, the constructor declared first in clazz is returned.

Parameters:
clazz - The class; cannot be null.
parameterTypes - The formal parameter types for the constructor to fetch.
Returns:
The (first) matching constructor; never null.
Throws:
NullPointerException - If clazz is null.
NoSuchMethodException - If no such constructor can be found.

getConstructors

public static <A extends Annotation> Constructor<?>[] getConstructors(Class<?> clazz,
                                                                      Class<A> annotation)
Returns the constructors declared in the class supplied as clazz annotated with the annotation type supplied as annotation.

Type Parameters:
A - The type of annotation.
Parameters:
clazz - The class; cannot be null.
annotation - The class representing the annotation type; cannot be null.
Returns:
An array containing the annotated constructors; never null, but can be empty.
Throws:
NullPointerException - If either argument is null.
See Also:
getMethods(Class, Class)

getCopyConstructor

public static final <T> Constructor<T> getCopyConstructor(Class<T> clazz)
Returns the copy constructor declared in clazz, if any.

A copy constructor of clazz is defined as a constructor accepting a single parameter of the exact same as clazz.

The constructor will be made accessible, if not already.

Type Parameters:
T - The type of class.
Parameters:
clazz - The class; cannot be null.
Returns:
The copy constructor, or null if no copy constructor is declared in clazz.
Throws:
NullPointerException - If clazz is null.

getFields

public static final List<Field> getFields(Class<?> clazz)
Returns all declared fields in clazz, or in a super-class or implemented interface. The fields are returned in a depth-first order, i.e. fields from super-classes or interfaces precede those from sub-classes (clazz).

Parameters:
clazz - The class to fetch the fields for; cannot be null.
Returns:
The list of fields; never null, but can be empty.
Throws:
NullPointerException - If clazz is null.

getInterfaces

public static final Set<Class<?>> getInterfaces(Class<?> clazz)
Returns an ordered set of the interfaces the Class supplied as clazz can be assigned to, including interfaces implemented by super-classes of clazz.

The returned set lists the interfaces in a depth first manner, i.e., interfaces from super-classes precedes interfaces from sub-classes. The order per class is the declaration order. A given interface is only included once in the set, corresponding to the first time visited.

Parameters:
clazz - The class to fetch the assignable interfaces for; cannot be null.
Returns:
An ordered set of the assignable interfaces; never null, but can be empty.
Throws:
NullPointerException - If clazz is null.

getInterfaces

public static final <C extends Collection<Class<?>>> C getInterfaces(Class<?> clazz,
                                                                     C interfaces)
Returns an ordered set of the interfaces the Class supplied as clazz can be assigned to, including interfaces implemented by super-classes of clazz.

The ordering of the interfaces is determined by the collection supplied as interfaces, but the interfaces will be added in a depth-first manner, i.e., interfaces from super-classes will be added before interfaces from sub-classes. The order per class is the declaration order.

If interfaces is a non-set collection, duplicates may occur.

Type Parameters:
C - The actual collection type to use.
Parameters:
clazz - The class to fetch the assignable interfaces for; cannot be null.
interfaces - The collection to add the interfaces to; cannot be null.
Returns:
The interfaces collection; never null, but can be empty.
Throws:
NullPointerException - If either argument is null.

getMethod

public static final Method getMethod(Class<?> clazz,
                                     String name,
                                     Class<?>... parameterTypes)
                              throws NoSuchMethodException
Returns the method with the name supplied as name that is declared in the class supplied as clazz accepting the formal parameter types supplied as parameterTypes, ignoring primitive types.

In case several methods match, the method declared first in clazz is returned.

Parameters:
clazz - The class; cannot be null.
name - The method name; cannot be null.
parameterTypes - The formal parameter types for the method to fetch.
Returns:
The (first) matching method; never null.
Throws:
NullPointerException - If clazz or name are null.
NoSuchMethodException - If no such method can be found.

getMethods

public static final List<Method> getMethods(Class<?> clazz)
Returns all declared methods in clazz, or in a super-class or implemented interface. The methods are returned in a depth-first order, i.e. methods from super-classes or interfaces precede those from sub-classes (clazz).

A unique method is only included once, but overridden versions may be included as well.

Parameters:
clazz - The class to fetch the methods for; cannot be null.
Returns:
The list of methods; never null, but can be empty if a clazz represents a marker interface.
Throws:
NullPointerException - If clazz is null.

getMethods

public static <A extends Annotation> Method[] getMethods(Class<?> clazz,
                                                         Class<A> annotation)
Returns the methods declared in the class supplied as clazz annotated with the annotation type supplied as annotation.

Type Parameters:
A - The type of annotation.
Parameters:
clazz - The class; cannot be null.
annotation - The class representing the annotation type; cannot be null.
Returns:
An array containing the annotated methods; never null, but can be empty.
Throws:
NullPointerException - If either argument is null.
See Also:
getConstructors(Class, Class)

getOverriding

public static final <T> KeyValue<Class<? super T>,Class<? super T>> getOverriding(Class<T> clazz,
                                                                                  String name,
                                                                                  Class<?>... types)
Returns a (key,value) placeholder, where the key is the first super class of clazz, or clazz it self, declaring a non-abstract method with the name supplied as name and the formal parameter types supplied as types, providing it is accessible to clazz, and where the value is the first super class of that class declaring a similar method. Hence, the class stored as the key declares the identified overriding method, and the class stored as the value declares the similar method being overridden.

If the value of the returned (key,value) placeholder is null, the method does not override any similar method from a super class. If the value is not null, the class stored as the value will be a regular super class of the class stored as the key.

If the returned placeholder is null, no such accessible method could be found in clazz, or in any of its super classes.

Java's normal visibility rules are applied in the check.

Type Parameters:
T - The type of the initial class.
Parameters:
clazz - The initial class to start the search for the method; cannot be null.
name - Method name; cannot be null.
types - Formal types of the method parameters, if any; can be empty.
Returns:
A (key,value) placeholder storing the relevant classes; can be null if no such method can be found in any super class, or clazz it self. The value will be null if the specified method does not override any similar method from a super class.
Throws:
NullPointerException - If clazz or name are null.
See Also:
isOverriding(Class, String, Class...), hasAccess(Class, Member)

getSuperClasses

public static final <T> List<Class<? super T>> getSuperClasses(Class<T> clazz)
Returns a list of all super-classes of clazz, excluding clazz, where the last index is always be Object.class.

Type Parameters:
T - The type of clazz.
Parameters:
clazz - The class to fetch the super-classes for; cannot be null.
Returns:
A list containing the super-classes; never null, but will be empty if clazz.equals(Object.class) is true.
Throws:
NullPointerException - If clazz is null.

hasAccess

public static final boolean hasAccess(Class<?> caller,
                                      Class<?> clazz)
Checks whether or not caller can access clazz based on Java's visibility rules.

Caution: the privilege check is performed without the use of a security manager, and is only based on the access modifiers and packages of caller and object!

Parameters:
caller - The caller class; cannot be null.
clazz - The clazz to test; cannot be null.
Returns:
True if caller has access, false if not.
Throws:
NullPointerException - If either parameter is null.
See Also:
hasAccess(Class, Member)

hasAccess

private static final boolean hasAccess(Class<?> caller,
                                       Class<?> clazz,
                                       int modifiers)
Checks whether or not the access modifiers supplied as modifiers allows caller to access to the owner of the modifiers declared in, or being, clazz.

An owner will thus be a member, e.g. method, or a class, e.g. clazz it self.

Parameters:
caller - The caller class; cannot be null.
clazz - The clazz to test; cannot be null.
modifiers - The access modifiers.
Returns:
True if modifiers allows caller to access the owner of the modifiers, false if not.
Throws:
NullPointerException - If either caller or clazz are null.

hasAccess

public static final boolean hasAccess(Class<?> caller,
                                      Member member)
Checks whether or not caller can access member based on Java's visibility rules.

Caution: the access check is performed without the use of a security manager, and is only based on the access modifiers and packages of of caller and member!

Parameters:
caller - The caller class; cannot be null.
member - The member to test; cannot be null.
Returns:
True if caller has access, false if not.
Throws:
NullPointerException - If either parameter is null.
See Also:
hasAccess(Class, Class)

invoke

public static final <E extends AccessibleObject & Member> Object invoke(Object target,
                                                                       E member,
                                                                       Object... arguments)
Returns the result of invoking the accessible member supplied as member.

The member can either be a method, constructor, or field.

If the member is a non-static method, constructor, or non-static field, target will be used as the target instance.

The member will be made accessible if not already.

Checked exceptions are suppressed to runtime exceptions.

Type Parameters:
E - The type of member.
Parameters:
target - The target if member is non static; can be null if member is static.
member - The member to invoke; cannot be null.
arguments - The arguments for member; can be null if member allows it. Unused if member is a field.
Returns:
The result of invoking member; can be null.
Throws:
NullPointerException - If member is null, or if target and/or arguments is null but not allowed by member.
RuntimeException - If the invocation fails.

isInstance

public static final boolean isInstance(boolean nullValuesMatch,
                                       Class<?>[] types,
                                       Object... values)
Returns true if each value in values is assignable to the corresponding type at the same index in types, respectively, false if not.

If objects is null and nullValuesMatch is true and types is empty, true will be returned; false otherwise. If nullValuesMatch is true, a null value will match the corresponding type in types at the same index.

The comparison is done ignoring primitives.

Parameters:
nullValuesMatch - True if null values in values will count as a match to the corresponding type, false if not.
types - The types; cannot be null.
values - The values; can be null.
Returns:
True if all values are instances of the corresponding types, false if not.
Throws:
NullPointerException - If types is null.

isInstance

public static final boolean isInstance(Class<?>[] types,
                                       Object... values)
Returns true if each value in values is assignable to the corresponding type at the same index in types, respectively, false if not.

If objects is null or contains null values, this method will always return false.

The comparison is done ignoring primitives.

Parameters:
types - The types; cannot be null.
values - The values; cannot be null.
Returns:
True if all values are instances of the corresponding types, false if not.
Throws:
NullPointerException - If types is null.

isOverriding

public static final boolean isOverriding(Class<?> clazz,
                                         String name,
                                         Class<?>... types)
Determines if a given accessible non-abstract method is overriding a similar method in a super class based on Java's visibility rules.

The overriding method, e.g. the method defined by name and the formal parameter types supplied as types overriding a similar method in a super class, need not be declared in clazz, but may be declared in any super class of it, providing it is accessible to clazz.

Parameters:
clazz - The initial class to start the search for the method; cannot be null.
name - Method name; cannot be null.
types - Formal types of the method parameters, if any; can be empty.
Returns:
True if such a method is overriding a similar method from a super class, false if not; the overriding method need not be declared in clazz, but can also be declared in any super class of it.
Throws:
NullPointerException - If clazz or name are null.
See Also:
getOverriding(Class, String, Class...), hasAccess(Class, Member)

isSubClass

public static final boolean isSubClass(Class<?> clazz,
                                       Class<?> subClass)
Returns true if and only if subClass is a sub-class of clazz, false otherwise.

For this method to return true, subClass must at some point extend clazz, directly or indirectly. Implementing common interfaces is not enough.

Parameters:
clazz - The parent class; cannot be null.
subClass - The sub-class; cannot be null.
Returns:
True if subClass is a sub-class of clazz, false if not.
Throws:
NullPointerException - If either argument is null.

isSuperClass

public static final boolean isSuperClass(Class<?> clazz,
                                         Class<?> superClass)
Returns true if and only if superClass is a super-class of clazz, false otherwise.

For this method to return true, clazz must at some point extend superClass, directly or indirectly. Implementing common interfaces is not enough.

Parameters:
clazz - The parent class; cannot be null.
superClass - The super-class; cannot be null.
Returns:
True if superClass is a super-class of clazz, false if not.
Throws:
NullPointerException - If either argument is null.

Gunni Rode / rode.dk

Feel free to use and/or modify the Java 6 source code developed for this thesis AT YOUR OWN RISK, but note that the source code comes WITHOUT ANY — and I do mean WITHOUT ANY — form of warranty WHAT SO EVER!

The original thesis and source code are available at rode.dk/thesis.