G eneric P roGramminG
138 ADVANCED JAVA PROGRAMMING
7.4 FINDING CLASS MEMBERS
There are three types of member a class may have: fields, methods and constructors. Java defines an interface Member that represents a single member. Each type of member is also represented as a separate class: Field, Method and Constructor. The class Class provides numerous methods to obtain those members. These methods may be grouped into two categories: i) methods that return a specific member such as field, method or constructor and ii) methods that return all members. Under each category there are again two sub-categories: i) methods that search only the current class and ii) methods that search for the super-classes and super-interfaces. Methods that only search the current class, return even private members, whereas methods that search super-classes and super-interfaces return only public members. The following sections describe how to use them to get class members.
7.4.1 Getting Fields
A field of a class is represented by the Field class that provides information about, and dynamic access to, a single field. The following methods are available to retrieve fields of a class:
public Field getDeclaredField(String name) public Field[] getDeclaredFields()
public Field getField(String name) public Field[] getFields()
The first one returns a single Field object corresponding to the specified field name, whereas the second one returns an array of Field corresponding to all fields. These two methods search only the fields declared (hence this word appears in the method name) in the class explicitly. The last two are the counterparts of the first two except that they search for super-class and
REFLECTION 141 super-interface. The following program accepts a fully qualified class name and prints a description of all declared fields in the class:
import java.lang.reflect.*; public class GetClassFields {
public static void main(String args[]) throws Exception { Class c = Class.forName(args[0]);
Field[] fields = c.getDeclaredFields();
System.out.println("No of fields in "+args[0]+": "+fields.length); for(Field f : fields)
System.out.println(f); }
}
To find all declared fields of Integer wrapper class, use the following command: java GetClassFields java.lang.Integer
It generates an output as follows:
No of fields in java.lang.Integer: 11
public static final int java.lang.Integer.MIN_VALUE public static final int java.lang.Integer.MAX_VALUE public static final java.lang.Class java.lang.Integer.TYPE static final char[] java.lang.Integer.digits
static final char[] java.lang.Integer.DigitTens static final char[] java.lang.Integer.DigitOnes static final int[] java.lang.Integer.sizeTable private final int java.lang.Integer.value public static final int java.lang.Integer.SIZE
private static final long java.lang.Integer.serialVersionUID static final boolean java.lang.Integer.$assertionsDisabled
If you want to get fields including inherited ones, use getFields() method instead. Note that getFields() methods only return public inherited methods. Note that there’s no built-in method that returns all the fields including the inherited ones. Using reflection, let us now write a program that retrieves all the fields:
import java.lang.reflect.*; public class GetAllClassFields {
public static void main(String args[]) throws Exception { print(Class.forName(args[0]));
}
static int v = 0;
static void print(Class c) { if(c != null) {
print(c.getSuperclass());
Field[] fields = c.getDeclaredFields(); indent(v); System.out.println("Class: "+c); for(Field f : fields) { indent(v); System.out.println(f); } v++; } }
static void indent(int n) {
for(int i=0;i<n;i++) System.out.print(" "); }
}
The method print() starts searching from the given class and works its way up the hierarchy recursively until either a field is found, or no super class is available. The print() method, on its way, displays all the fields including the private ones. The method indent() has been used to indent the output.
7.4.2 Getting Methods
A method of a class is represented by the Method class that provides information about, and access to, a single method. The following methods are available to retrieve methods of a class:
public Method getDeclaredMethod(String name, Class<?>... parameterTypes) public Method[] getDeclaredMethods()
public Method getMethod(String name, Class<?>... parameterTypes) public Method[] getMethods()
The functionality of these methods is similar to the methods available for fields except that these return method instead of field. The following program illustrates how to get all declared methods of a specified class:
import java.lang.reflect.*; public class GetClassMethods {
public static void main(String args[]) throws Exception { Class c = Class.forName(args[0]);
Method[] methods = c.getDeclaredMethods();
System.out.println("No. of methods in "+args[0]+": "+methods.length); for(Method m : methods)
System.out.println(m); }
}
Use the following command to find all methods of Member interface: java GetClassMethods java.lang.reflect.Member
It results in the following output:
No. of methods in java.lang.reflect.Member: 4
public abstract java.lang.String java.lang.reflect.Member.getName()
public abstract java.lang.Class java.lang.reflect.Member.getDeclaringClass() public abstract int java.lang.reflect.Member.getModifiers()
public abstract boolean java.lang.reflect.Member.isSynthetic()
Note that this program, retrieves even the private methods of the class. Use the following command to find all methods of java.lang.Class class:
java GetClassMethods java.lang.Class
If you want to get methods including inherited ones, use getMethods() method instead. The following finds all methods of a class including inherited and private methods:
import java.lang.reflect.*; public class GetAllClassMethods {
public static void main(String args[]) throws Exception { print(Class.forName(args[0]));
}
static int v = 0;
static void print(Class c) { if(c != null) {
print(c.getSuperclass());
Method[] methods = c.getDeclaredMethods(); indent(v); System.out.println("Class: "+c); for(Method m : methods) { indent(v); System.out.println(m); } v++; } }
static void indent(int n) {
for(int i=0;i<n;i++) System.out.print(" "); }
REFLECTION 143
7.4.3 Getting Constructors
Since, constructors are special methods, reflection API provides a separate class Constructor that provides information about, and access to, a single constructor. The following methods are available to retrieve constructors of a class:
public Constructor<T> getDeclaredConstructor(Class<?>... parameterTypes) public Constructor<?>[] getDeclaredConstructors()
public Constructor<T> getConstructor(Class<?>... parameterTypes) public Constructor<?>[] getConstructors()
Since, constructors are not inherited, the last two methods return only public constructor(s). The following program retrieves all constructors of a specified class:
import java.lang.reflect.*;
public class GetClassConstructors {
public static void main(String args[]) throws Exception { Class c = Class.forName(args[0]);
Constructor[] cons = c.getDeclaredConstructors();
System.out.println("No of constructors in "+args[0]+": "+cons.length); for(Constructor con : cons)
System.out.println(con); }
}
Use the following command to find all methods of java.lang.Boolean class: java GetClassConstructors java.lang.Boolean
The sample result is shown below:
No of constructors in java.lang.Boolean: 2 public java.lang.Boolean(boolean)
public java.lang.Boolean(java.lang.String)