Reflection

In this chapter you will learn:

  1. What is Java Reflection
  2. What are the useful classes we can use to do reflection in Java

What is Java 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;
/*  ja v  a2  s. co m*/
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);
    }
  }
}

The code above uses Java reflection to get all constructors, methods and fields for class Dimension from package java.awt. java.awt is a Java system package which is owned by Java vendor. Dimension is created and coded by someone we don't know. But through Java reflection we can still find out all information about a class.

Here is the output from this program:

Constructors:/*ja  v  a  2s . c  o m*/
 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()

Useful classes for reflection

The following table lists the classes from java.lang.reflect package which we can use to get information about a class, a method or a field.

Class Primary Function
AccessibleObject Allows you to bypass the default access control checks.
Array Allows you to dynamically create and manipulate arrays.
Constructor Provides information about a constructor.
Field Provides information about a field.
Method Provides information about a method.
Modifier Provides information about class and member access modifiers.
Proxy Supports dynamic proxy classes.
ReflectPermissionAllows reflection of private or protected members of a class.

The following code uses reflection to decompile a type. It uses the classes from java.lang.reflect package. The following chapters will talk about classes from java.lang.reflect package.

import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
/*j  a  v a  2 s . c o  m*/
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:

Next chapter...

What you will learn in the next chapter:

  1. What is java.lang.Class
  2. How to load class from class name
  3. How to get the class name
  4. How to check the type of a class
  5. How to create new instance with reflection
Home » Java Tutorial » Reflection
Reflection
Class Reflection
Class modifier, package and string presentation
Constructor reflection
Field Reflection
Get/Set field value
Java method reflection
Modifier
Package
Array reflection
Get annotation type
Method annotation