What is Reflection

Reflection is the ability of software to analyze itself.

Java's Reflection API lets applications learn about loaded classes, interfaces, enums (a kind of class), and annotation types (a kind of interface).

It can load classes dynamically, instantiate them, find a class's fields and methods, access fields, call methods, and perform other tasks.

The following application illustrates a simple use of the Java reflection capabilities.



import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.Method;

public class Main {
  public static void main(String args[]) {
    try {
      Class c = Class.forName("java.awt.Dimension");
      System.out.println("Constructors:");
      Constructor constructors[] = c.getConstructors();
      for (int i = 0; i < constructors.length; i++) {
        System.out.println(" " + constructors[i]);
      }
      System.out.println("Fields:");
      Field fields[] = c.getFields();
      for (int i = 0; i < fields.length; i++) {
        System.out.println(" " + fields[i]);
      }
      System.out.println("Methods:");
      Method methods[] = c.getMethods();
      for (int i = 0; i < methods.length; i++) {
        System.out.println(" " + methods[i]);
      }
    } catch (Exception e) {
      System.out.println("Exception: " + e);
    }
  }
}  

Here is the output from this program:


Constructors:
 public java.awt.Dimension(java.awt.Dimension)
 public java.awt.Dimension(int,int)
 public java.awt.Dimension()
Fields:
 public int java.awt.Dimension.width
 public int java.awt.Dimension.height
Methods:
 public int java.awt.Dimension.hashCode()
 public boolean java.awt.Dimension.equals(java.lang.Object)
 public java.lang.String java.awt.Dimension.toString()
 public java.awt.Dimension java.awt.Dimension.getSize()
 public void java.awt.Dimension.setSize(int,int)
 public void java.awt.Dimension.setSize(double,double)
 public void java.awt.Dimension.setSize(java.awt.Dimension)
 public double java.awt.Dimension.getHeight()
 public double java.awt.Dimension.getWidth()
 public java.lang.Object java.awt.geom.Dimension2D.clone()
 public void java.awt.geom.Dimension2D.setSize(java.awt.geom.Dimension2D)
 public final native java.lang.Class java.lang.Object.getClass()
 public final void java.lang.Object.wait(long,int) throws java.lang.InterruptedException
 public final void java.lang.Object.wait() throws java.lang.InterruptedException
 public final native void java.lang.Object.wait(long) throws java.lang.InterruptedException
 public final native void java.lang.Object.notify()
 public final native void java.lang.Object.notifyAll()
ClassPrimary Function
AccessibleObjectAllows you to bypass the default access control checks.
ArrayAllows you to dynamically create and manipulate arrays.
ConstructorProvides information about a constructor.
FieldProvides information about a field.
MethodProvides information about a method.
ModifierProvides information about class and member access modifiers.
ProxySupports dynamic proxy classes.
ReflectPermissionAllows reflection of private or protected members of a class.

The following code uses reflection to decompile a type

 
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;

public class Main {
  public static void main(String[] args) {
    try {
      decompileClass(Class.forName("java.lang.String"), 0);
    } catch (ClassNotFoundException cnfe) {
      System.err.println("could not locate " + args[0]);
    }
  }

  static void decompileClass(Class<?> clazz, int indentLevel) {
    System.out.print(Modifier.toString(clazz.getModifiers()) + " ");
    if (clazz.isEnum())
      System.out.println("enum " + clazz.getName());
    else if (clazz.isInterface()) {
      if (clazz.isAnnotation()){
        System.out.print("@");
      }
      System.out.println(clazz.getName());
    } else{
      System.out.println(clazz);
    }
    System.out.println("{");
    Field[] fields = clazz.getDeclaredFields();
    for (int i = 0; i < fields.length; i++) {
      System.out.println(" " + fields[i]);
    }
    Constructor[] constructors = clazz.getDeclaredConstructors();
    if (constructors.length != 0 && fields.length != 0){
      System.out.println();
    }
      
    for (int i = 0; i < constructors.length; i++) {
      System.out.println(" " + constructors[i]);
    }
    Method[] methods = clazz.getDeclaredMethods();
    if (methods.length != 0 && (fields.length != 0 || constructors.length != 0))
      System.out.println();
    for (int i = 0; i < methods.length; i++) {
      System.out.println(" " + methods[i]);
    }
    Method[] methodsAll = clazz.getMethods();
    if (methodsAll.length != 0 && (fields.length != 0 || constructors.length != 0 || methods.length != 0)){
      System.out.println();      
    }
    if (methodsAll.length != 0) {
      System.out.println(" ALL PUBLIC METHODS");
      System.out.println();
    }
    for (int i = 0; i < methodsAll.length; i++) {
      System.out.println(" " + methodsAll[i]);
    }
    Class<?>[] members = clazz.getDeclaredClasses();
    if (members.length != 0 && (fields.length != 0 || 
        constructors.length != 0 || methods.length != 0 || 
        methodsAll.length != 0)){
      System.out.println();
    }      
    for (int i = 0; i < members.length; i++){
      if (clazz != members[i]) {
        decompileClass(members[i], indentLevel + 1);
        if (i != members.length - 1){
          System.out.println();
        }          
      }
    }
    System.out.println("}");
  }
}
  

Output:


public final class java.lang.String
{
 private final char[] java.lang.String.value
 private final int java.lang.String.offset
 private final int java.lang.String.count
 private int java.lang.String.hash
 private static final long java.lang.String.serialVersionUID
 private static final java.io.ObjectStreamField[] java.lang.String.serialPersistentFields
 public static final java.util.Comparator java.lang.String.CASE_INSENSITIVE_ORDER

 public java.lang.String()
 public java.lang.String(java.lang.String)
 public java.lang.String(char[])
 public java.lang.String(char[],int,int)
 public java.lang.String(int[],int,int)
 public java.lang.String(byte[],int,int,int)
 public java.lang.String(byte[],int)
 public java.lang.String(java.lang.StringBuilder)
 public java.lang.String(byte[],int,int,java.lang.String) throws java.io.UnsupportedEncodingException
 public java.lang.String(byte[],int,int,java.nio.charset.Charset)
 public java.lang.String(byte[],java.lang.String) throws java.io.UnsupportedEncodingException
 public java.lang.String(byte[],java.nio.charset.Charset)
 public java.lang.String(byte[],int,int)
 public java.lang.String(byte[])
 public java.lang.String(java.lang.StringBuffer)
 java.lang.String(int,int,char[])

 public boolean java.lang.String.equals(java.lang.Object)
 public java.lang.String java.lang.String.toString()
 public int java.lang.String.hashCode()
 public int java.lang.String.compareTo(java.lang.String)
 public int java.lang.String.compareTo(java.lang.Object)
 public int java.lang.String.indexOf(int)
 public int java.lang.String.indexOf(int,int)
 public int java.lang.String.indexOf(java.lang.String)
 public int java.lang.String.indexOf(java.lang.String,int)
 static int java.lang.String.indexOf(char[],int,int,char[],int,int,int)
 public static java.lang.String java.lang.String.valueOf(int)
 public static java.lang.String java.lang.String.valueOf(char)
 public static java.lang.String java.lang.String.valueOf(boolean)
 public static java.lang.String java.lang.String.valueOf(float)
 public static java.lang.String java.lang.String.valueOf(char[],int,int)
 public static java.lang.String java.lang.String.valueOf(double)
 public static java.lang.String java.lang.String.valueOf(char[])
 public static java.lang.String java.lang.String.valueOf(java.lang.Object)
 public static java.lang.String java.lang.String.valueOf(long)
 public char java.lang.String.charAt(int)
 private static void java.lang.String.checkBounds(byte[],int,int)
 public int java.lang.String.codePointAt(int)
 public int java.lang.String.codePointBefore(int)
 public int java.lang.String.codePointCount(int,int)
 public int java.lang.String.compareToIgnoreCase(java.lang.String)
 public java.lang.String java.lang.String.concat(java.lang.String)
 public boolean java.lang.String.contains(java.lang.CharSequence)
 public boolean java.lang.String.contentEquals(java.lang.CharSequence)
 public boolean java.lang.String.contentEquals(java.lang.StringBuffer)
 public static java.lang.String java.lang.String.copyValueOf(char[])
 public static java.lang.String java.lang.String.copyValueOf(char[],int,int)
 public boolean java.lang.String.endsWith(java.lang.String)
 public boolean java.lang.String.equalsIgnoreCase(java.lang.String)
 public static java.lang.String java.lang.String.format(java.lang.String,java.lang.Object[])
 public static java.lang.String java.lang.String.format(java.util.Locale,java.lang.String,java.lang.Object[])
 public byte[] java.lang.String.getBytes(java.lang.String) throws java.io.UnsupportedEncodingException
 public void java.lang.String.getBytes(int,int,byte[],int)
 public byte[] java.lang.String.getBytes()
 public byte[] java.lang.String.getBytes(java.nio.charset.Charset)
 public void java.lang.String.getChars(int,int,char[],int)
 void java.lang.String.getChars(char[],int)
 public native java.lang.String java.lang.String.intern()
 public boolean java.lang.String.isEmpty()
 public int java.lang.String.lastIndexOf(java.lang.String)
 public int java.lang.String.lastIndexOf(int,int)
 public int java.lang.String.lastIndexOf(int)
 public int java.lang.String.lastIndexOf(java.lang.String,int)
 static int java.lang.String.lastIndexOf(char[],int,int,char[],int,int,int)
 public int java.lang.String.length()
 public boolean java.lang.String.matches(java.lang.String)
 public int java.lang.String.offsetByCodePoints(int,int)
 public boolean java.lang.String.regionMatches(boolean,int,java.lang.String,int,int)
 public boolean java.lang.String.regionMatches(int,java.lang.String,int,int)
 public java.lang.String java.lang.String.replace(java.lang.CharSequence,java.lang.CharSequence)
 public java.lang.String java.lang.String.replace(char,char)
 public java.lang.String java.lang.String.replaceAll(java.lang.String,java.lang.String)
 public java.lang.String java.lang.String.replaceFirst(java.lang.String,java.lang.String)
 public java.lang.String[] java.lang.String.split(java.lang.String)
 public java.lang.String[] java.lang.String.split(java.lang.String,int)
 public boolean java.lang.String.startsWith(java.lang.String)
 public boolean java.lang.String.startsWith(java.lang.String,int)
 public java.lang.CharSequence java.lang.String.subSequence(int,int)
 public java.lang.String java.lang.String.substring(int)
 public java.lang.String java.lang.String.substring(int,int)
 public char[] java.lang.String.toCharArray()
 public java.lang.String java.lang.String.toLowerCase()
 public java.lang.String java.lang.String.toLowerCase(java.util.Locale)
 public java.lang.String java.lang.String.toUpperCase()
 public java.lang.String java.lang.String.toUpperCase(java.util.Locale)
 public java.lang.String java.lang.String.trim()

 ALL PUBLIC METHODS

 public boolean java.lang.String.equals(java.lang.Object)
 public java.lang.String java.lang.String.toString()
 public int java.lang.String.hashCode()
 public int java.lang.String.compareTo(java.lang.String)
 public int java.lang.String.compareTo(java.lang.Object)
 public int java.lang.String.indexOf(int)
 public int java.lang.String.indexOf(int,int)
 public int java.lang.String.indexOf(java.lang.String)
 public int java.lang.String.indexOf(java.lang.String,int)
 public static java.lang.String java.lang.String.valueOf(int)
 public static java.lang.String java.lang.String.valueOf(char)
 public static java.lang.String java.lang.String.valueOf(boolean)
 public static java.lang.String java.lang.String.valueOf(float)
 public static java.lang.String java.lang.String.valueOf(char[],int,int)
 public static java.lang.String java.lang.String.valueOf(double)
 public static java.lang.String java.lang.String.valueOf(char[])
 public static java.lang.String java.lang.String.valueOf(java.lang.Object)
 public static java.lang.String java.lang.String.valueOf(long)
 public char java.lang.String.charAt(int)
 public int java.lang.String.codePointAt(int)
 public int java.lang.String.codePointBefore(int)
 public int java.lang.String.codePointCount(int,int)
 public int java.lang.String.compareToIgnoreCase(java.lang.String)
 public java.lang.String java.lang.String.concat(java.lang.String)
 public boolean java.lang.String.contains(java.lang.CharSequence)
 public boolean java.lang.String.contentEquals(java.lang.CharSequence)
 public boolean java.lang.String.contentEquals(java.lang.StringBuffer)
 public static java.lang.String java.lang.String.copyValueOf(char[])
 public static java.lang.String java.lang.String.copyValueOf(char[],int,int)
 public boolean java.lang.String.endsWith(java.lang.String)
 public boolean java.lang.String.equalsIgnoreCase(java.lang.String)
 public static java.lang.String java.lang.String.format(java.lang.String,java.lang.Object[])
 public static java.lang.String java.lang.String.format(java.util.Locale,java.lang.String,java.lang.Object[])
 public byte[] java.lang.String.getBytes(java.lang.String) throws java.io.UnsupportedEncodingException
 public void java.lang.String.getBytes(int,int,byte[],int)
 public byte[] java.lang.String.getBytes()
 public byte[] java.lang.String.getBytes(java.nio.charset.Charset)
 public void java.lang.String.getChars(int,int,char[],int)
 public native java.lang.String java.lang.String.intern()
 public boolean java.lang.String.isEmpty()
 public int java.lang.String.lastIndexOf(java.lang.String)
 public int java.lang.String.lastIndexOf(int,int)
 public int java.lang.String.lastIndexOf(int)
 public int java.lang.String.lastIndexOf(java.lang.String,int)
 public int java.lang.String.length()
 public boolean java.lang.String.matches(java.lang.String)
 public int java.lang.String.offsetByCodePoints(int,int)
 public boolean java.lang.String.regionMatches(boolean,int,java.lang.String,int,int)
 public boolean java.lang.String.regionMatches(int,java.lang.String,int,int)
 public java.lang.String java.lang.String.replace(java.lang.CharSequence,java.lang.CharSequence)
 public java.lang.String java.lang.String.replace(char,char)
 public java.lang.String java.lang.String.replaceAll(java.lang.String,java.lang.String)
 public java.lang.String java.lang.String.replaceFirst(java.lang.String,java.lang.String)
 public java.lang.String[] java.lang.String.split(java.lang.String)
 public java.lang.String[] java.lang.String.split(java.lang.String,int)
 public boolean java.lang.String.startsWith(java.lang.String)
 public boolean java.lang.String.startsWith(java.lang.String,int)
 public java.lang.CharSequence java.lang.String.subSequence(int,int)
 public java.lang.String java.lang.String.substring(int)
 public java.lang.String java.lang.String.substring(int,int)
 public char[] java.lang.String.toCharArray()
 public java.lang.String java.lang.String.toLowerCase()
 public java.lang.String java.lang.String.toLowerCase(java.util.Locale)
 public java.lang.String java.lang.String.toUpperCase()
 public java.lang.String java.lang.String.toUpperCase(java.util.Locale)
 public java.lang.String java.lang.String.trim()
 public final native void java.lang.Object.wait(long) throws java.lang.InterruptedException
 public final void java.lang.Object.wait() throws java.lang.InterruptedException
 public final void java.lang.Object.wait(long,int) throws java.lang.InterruptedException
 public final native java.lang.Class java.lang.Object.getClass()
 public final native void java.lang.Object.notify()
 public final native void java.lang.Object.notifyAll()

static class java.lang.String$1
{
 ALL PUBLIC METHODS

 public final native void java.lang.Object.wait(long) throws java.lang.InterruptedException
 public final void java.lang.Object.wait() throws java.lang.InterruptedException
 public final void java.lang.Object.wait(long,int) throws java.lang.InterruptedException
 public boolean java.lang.Object.equals(java.lang.Object)
 public java.lang.String java.lang.Object.toString()
 public native int java.lang.Object.hashCode()
 public final native java.lang.Class java.lang.Object.getClass()
 public final native void java.lang.Object.notify()
 public final native void java.lang.Object.notifyAll()
}

private static class java.lang.String$CaseInsensitiveComparator
{
 private static final long java.lang.String$CaseInsensitiveComparator.serialVersionUID

 private java.lang.String$CaseInsensitiveComparator()
 java.lang.String$CaseInsensitiveComparator(java.lang.String$1)

 public int java.lang.String$CaseInsensitiveComparator.compare(java.lang.String,java.lang.String)
 public int java.lang.String$CaseInsensitiveComparator.compare(java.lang.Object,java.lang.Object)

 ALL PUBLIC METHODS

 public int java.lang.String$CaseInsensitiveComparator.compare(java.lang.String,java.lang.String)
 public int java.lang.String$CaseInsensitiveComparator.compare(java.lang.Object,java.lang.Object)
 public final native void java.lang.Object.wait(long) throws java.lang.InterruptedException
 public final void java.lang.Object.wait() throws java.lang.InterruptedException
 public final void java.lang.Object.wait(long,int) throws java.lang.InterruptedException
 public boolean java.lang.Object.equals(java.lang.Object)
 public java.lang.String java.lang.Object.toString()
 public native int java.lang.Object.hashCode()
 public final native java.lang.Class java.lang.Object.getClass()
 public final native void java.lang.Object.notify()
 public final native void java.lang.Object.notifyAll()
}
}
Home 
  Java Book 
    Reflection