- Analyze the capabilities of classes at runtime;
- Inspect objects at runtime–for example, to write a single toString method that works for all classes;
- Implement generic array manipulation code;
- Taking advantage of Method objects that work just like function pointers in languages such as C++.
The Class Class
While your program is running, the Java runtime system always maintains what is called runtime type identification on all objects. This information keeps track of the class to which each object belongs. Runtime type information is used by the virtual machine to select the correct methods to execute.
However, you can also access this information by working with a special Java class. The class that holds this information is called, somewhat confusingly, Class. The getClass() method in the Object class returns an instance of Class type.
C++ Note:
The newInstance method corresponds to the idiom of a virtual constructor in C++. However, virtual constructors in C++ are not a language feature but just an idiom taht needs to be supported by a specialized library. The Class class is similar to the type_info class in C++, and the getClass method is equivalent to the typeid operator. The Java Class is quite a bit more versatile than type_info, though. The C++ type_info can only reveal a string with the name of the type, not create new objects of that type.
A Primer on Catching Exceptions
java.lang.Class
- static Class forName(String className)
returns the Class object representing the class with name className. - Object newInstance()
returns a new instance of this class.
java.lang.reflect.Constructor - Object newInstance(Object[] args)
constructs a new instance of the constructor’s declaring class.
Parameters: args the parameters supplied to the constructor. See the section on reflection for more information on how to supply parameters.
java.lang.Throwable - void printStackTrace()
prints the Throwable object and stack trace to the standard error stream.
Using Reflection to Analyze the Capabilities of Classes
ReflectionTest.java
import java.util.*;
import java.lang.reflect.*;
public class Test {
public static void main(String[] args) {
// read class name from command line args or user input
String name;
if (args.length > 0)
name = args[0];
else {
Scanner in = new Scanner(System.in);
System.out.println("Enter class name (e.g java.util.Date):");
name = in.next();
}
try {
// print class name and superclass name (if != Object)
Class c1 = Class.forName(name);
Class superc1 = c1.getSuperclass();
String modifiers = Modifier.toString(c1.getModifiers());
if (modifiers.length() > 0)
System.out.print(modifiers + " ");
System.out.print("class " + name);
if (superc1 != null && superc1 != Object.class)
System.out.println("extends " + superc1.getName());
System.out.print("n{n");
printConstructors(c1);
System.out.println();
printFields(c1);
System.out.println("}");
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
System.exit(0);
}
public static void printConstructors(Class c1) {
Constructor[] constructors = c1.getDeclaredConstructors();
for (Constructor c : constructors) {
String name = c.getName();
System.out.print(" ");
String modifiers = Modifier.toString(c.getModifiers());
if (modifiers.length() > 0)
System.out.print(modifiers + " ");
System.out.print(name + "(");
// print parameter types
Class[] paramTypes = c.getParameterTypes();
for (int j = 0; j < paramTypes.length; j++) {
if (j > 0)
System.out.print(", ");
System.out.print(paramTypes[j].getName());
}
System.out.println(");");
}
}
public static void printMethods(Class c1) {
Method[] mmethods = c1.getDeclaredMethods();
for (Method m : mmethods) {
Class retType = m.getReturnType();
String name = m.getName();
System.out.println(" ");
// print modifiers, return type and method name
String modifiers = Modifier.toString(m.getModifiers());
if (modifiers.length() > 0)
System.out.print(modifiers + " ");
System.out.print(retType.getName() + " " + "(");
// print parameter types
Class[] paramTypes = m.getParameterTypes();
for (int j = 0; j < paramTypes.length; j++) {
if (j > 0)
System.out.print(", ");
System.out.print(paramTypes[j].getName());
}
System.out.println(");");
}
}
public static void printFields(Class c1) {
Field[] fields = c1.getDeclaredFields();
for (Field f : fields) {
Class type = f.getType();
String name = f.getName();
System.out.print(" ");
String modifiers = Modifier.toString(f.getModifiers());
if (modifiers.length() > 0)
System.out.print(modifiers + " ");
System.out.println(type.getName() + " " + name + ";");
}
}
}
if you enter
java.lang.Double
the program prints



