Concept:
Reflection is the ability of a running program to examine itself and its software environment, and to change what it does depending on what it finds. A reflective solution often starts with querying information about the running program from metaobjects. After gathering information using introspection, a reflective program uses that information to make changes in the behavior of the program.

To perform this self-examination, a program needs to have a representation of itself, which is metadata. Metadata is organized into objects, called metaobjects. The runtime of self-examination of the metaobjects is called introspection.

Metaobjects often provide ways of changing program structure, behavior, or data. E.g. dynamic invocation to call a method found by introspection; reflective construction, dynamic loading, and intercepting method calls.

There are 3 issues that have impeded the use of reflection:
 1. security
 2. code complexity
 3. runtime performance (Dynamic invocation introduces latency by resolving which method to call and checking access at runtime rather than at compile time).

Examples:
If each of the components in a project provides a XXX() method, now we want to call XXX() regardless of a component's concrete type.

Alternatives for reflection:
Method 1. If it is able to control the source code, the components could be refactored to implement a common interface that declares XXX().
Method 2. Implement an adapter for each component. But the method will cause an explosion of the number of objects in the system at runtime and to maintain.
Method 3. Useing instaceof at runtime. But the code will bloat with conditionals and casts, and couple tightly with each concrete type.

Sample Code:
Class cls = obj.getClass() //Query object for its class
try
{
      Method method = cls.getMethod("XXX", new Class[]{ });  //The 2nd parameter is legal to supply null for a parameterless method.
      method.invoke( obj, new Object[]{ }); //Call resulting method on target obj //The 2nd parameter is legal to supply null for a parameterless method.
}
catch(NoSuchMethodException e){} //Class of obj does not support XXX() method
catch{IllegalAccessException e){} //Invoker cannot call XXX()
catch{InvocationTargetException){} //XXX() throws an exception

Methods:
getDeclaredMethod() & getDeclaredMethods() return methods of all visibilities -- public, protected, package and private.
getMethod() & getMethods() return only a class's public methods, but both declared and inherited.

new Class[]{A}. 
      A could be e.g. Collection.class (object), int.class (primitive), void.class, Object[].class (array)

method.invoke( obj, new Object[]{ }). 
      The first parameter is igored when the method is a static method. So it could be null in this case.

int code = ((Integer)method.invoke(obj, null)).intValue()
      If the method being invoked is declared with a void return, invoke returns the value null. Primitives need to be wrapped when passed into a dynamic invocation and unwrapped when received as a return value.

Recursive Method:
public static Method getSupportedMethod( Class cls, String name, Class[] paramTypes)
{
      if (cls == null) {throw new NoSuchMethodException();}
      try
      {
            return cls.getDelaredMethod( name, paramTypes );
      }
      catch (NoSuchMethodException ex)
      {
            return getSupportedMethod( cls.getSuperclass(), name, paramType );
      }
}
All public methods of the class (declared and inherited) -> all methods of the class (declared) - > all methods of superclass (declared)

Instace:
The class object for Class is an instance of  itself: Class.class.isInstance(Class.class)
The class object for Class is an instance of Object: Class.class.isInstace(Object.class)