Reflection
In this chapter you will learn:
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. |
ReflectPermission | Allows 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:
- What is java.lang.Class
- How to load class from class name
- How to get the class name
- How to check the type of a class
- How to create new instance with reflection