TOC
BACK
FORWARD
HOME

Java 1.1 Unleashed

- 18 -
The Reflection Package

by Corey Klaasmeyer

IN THIS CHAPTER

  • The Class Class
  • The Member Interface
  • The Field Class
  • The Method Class
  • The Constructor Class
  • The Array Class
  • The Modifier Class

The reflection package (java.lang.reflect) allows you to peer into the Java virtual machine and gather information about classes and objects. JavaBeans application builder tools make use of these classes as do compilers and debuggers that need access to class-level information. Object serialization classes must also inspect objects to pack and unpack objects. This chapter describes the major classes of the reflection package and their uses.

Java 1.1 added new methods to the Class class to support reflection. Although the Class class should really be a member of the java.lang.reflect package, it remains a member of java.lang for backwards compatibility. For this reason, a portion of the Class methods are covered in Chapter 10, "The Language Package," as part of the java.lang package; the rest of the methods of Class are covered in this chapter. This chapter focuses on methods relevant to the java.lang.reflect subpackage. The Exception classes defined in this package are covered in Chapter 7, "Exception Handling."

The Class Class

The Class class plays a central role in the reflection package by providing runtime access to classes and interfaces through Class objects. Instances of these Class objects are created by calling the static method forName() of class Class. These Class objects are representations, or reflections, of their respective classes and interfaces. Methods of the Class class return instances of Field, Method, Constructor, Array, and Modifier classes, which you can then use to access and modify members of the reflected classes and interfaces.


NOTE: The Class, Field, Method, Constructor, and Array classes all have private constructors. Only the Java virtual machine can create new instances of these classes.

The following methods play important roles in the java.lang.reflect classes:

  • boolean isInstance(Object obj)

  • boolean isInterface(

  • boolean isArray()

  • boolean isPrimitive()

  • int getModifiers()

  • Field[] getFields()

  • Field getField(String name)

  • Method[] getMethods()

  • Method getMethod(String name, Class[] parameterTypes )

  • Constructor[] getConstructors()

  • Constructor getConstructor(Class[] parameterTypes)

  • Class[] getDeclaredClasses()

  • Field[] getDeclaredFields()

  • Method[] getDeclaredMethods()

The isInstance() Method

boolean isInstance(Object obj)

The isInstance() method works like the instanceof operator. If the Object argument is not null and can be cast to the type of the Class object without throwing an exception, the method returns true.

Object o = new Object();
Class instance = Class.forName("java.lang.StringBuffer");
System.out.println( instance.isInstance( o ) );

This code segment prints false because a reference of type Object cannot be cast to a StringBuffer type.

The isInterface() Method

boolean isInterface()

The isInterface() method returns true if the Class object represents an interface type. The isInterface() method can be used in the following way:

Class instance = Class.forName("java.lang.image.ImageObserver");
System.out.println( instance.isInterface() );

This code prints true because ImageObserver is an interface.

The isArray() Method

boolean isArray()

The isArray() method returns true if the Class object represents an array type; it returns false if not. This method can be used as follows:

Class instance = Class.forName("java.awt.image.ImageObserver");
System.out.println( instance.isArray() );

This example outputs false because the ImageObserver class is not an array type.

The isPrimitive() Method

boolean isPrimitive()

The isPrimitive() method returns true if the Class object represents a primitive type; it returns false if not. The following is an example of its use:

System.out.println( Integer.TYPE.isPrimitive() );

This example prints true because the final static class variable Integer.TYPE is an object representing the primitive type int. This TYPE class variable is a member of all the type wrapper classes, including the new class Void. In fact, Void contains nothing but the TYPE class variable.

The getModifiers() Method

int getModifiers()

Although you may guess that the getModifiers() method returns an array of modifiers, it actually returns an int. The static method toString() of the Modifier class can then be used to return the set of modifiers represented by this int value. The following example illustrates this process:

Class instance = Class.forName("java.lang.StringBuffer");
int modifiers = instance.getModifiers();
System.out.println(Modifier.toString(modifiers));

This code segment prints all the modifiers found in the definition of the StringBuffer class:

public final synchronized

The getFields() Method

Field[] getFields()

The getFields() method returns an array of Field objects representing all the member fields of the reflected interface or class. All the public fields of the superclass or superinterface are included in this array. Each of the Field objects in the array represents a single class (static) variable or instance variable. If no public fields are found in the reflected class, an array of length zero is returned. The following example uses the getFields() method to gather information about the Event class; the method returns an array of 74 public instance and class variables:

Class instance = Class.forName( "java.awt.Event" );
Field[] result = null;
result = instance.getFields();

for( int i = 0 ; i < Array.getLength( result ) ; i++ ) { 
System.out.println( result[i].toString() ); }

See the discussion of the toString() method, in the section "The Field Class," later in this chapter for information about what the output from this code snippet looks like.

The getField() Method

Field getField(String name)

The getField() method returns a single Field object with a name matching the String argument. To find the field with the specified name, the getField() method searches all the public instance fields or static fields of the reflected class or object and all the public fields of the superclass or superinterface. If no fields matching that name are found, a NoSuchFieldException exception is thrown. The following example shows how to find the id variable in the Event object:

Class instance = Class.forName( "java.awt.Event" );
Field result = instance.getField( "id" );
System.out.println( result.toString() );

In this example, the getField() method searches for the instance variable "id" within the reflected Event class. It finds the field and prints the following information about the field:

public int java.awt.Event.id

The getMethods() Method

Method[] getMethods()

The getMethods() method can be used in the same way as the getFields() method just described. Instead of returning Field objects, however, the getMethods() method returns all the public methods of the reflected interface or class and the public methods of any superclasses or superinterfaces. If no public methods are found, the method returns an array of length zero. Here is an example showing how this method is called on a Class object representing the String class:

Class instance = Class.forName( "java.lang.String" );
Method[] result = instance.getMethods();

for( int i = 0 ; i < result.length ; i++ ) { 
System.out.println( result[i].toString() ); }

This example prints out all the public methods in the String class as well as all the public methods of the Object class. The toString() method of the Method class describes more fully how the output from this example is formatted.

The getMethod() Method

Method getMethod(String name, Class[] parameterTypes)

The getMethod() method returns a Method object representing a method with the same name as the String argument. An array of Class objects is sent as the second argument to the method to distinguish between overridden and overloaded methods with the same names. Because a method signature is defined by number of parameters, types of parameters, as well as order of parameters, the order of the Class objects in the Class[] array parameter is important. If no method by that signature is found, the method throws a NoSuchMethodException exception. The getMethod() method can be used as in the following example:

Class instance = Class.forName("java.lang.String");
Class[] array = new Class[2];
array[0] = Class.forName("java.lang.String");
array[1] = Integer.TYPE;
System.out.println(instance.getMethod("indexOf",array).toString());

The fourth line in this code segment is interesting because it uses the new static final class variable TYPE, which is a member of the Integer class. The variable contains a reference to an object of class Class, which in this case represents the int type. The new primitive Class objects are discussed in the example code of the isPrimitive() method, presented earlier in this chapter.

The getConstructors() Method

Constructor[] getConstuctors()

The getConstructors() method returns an array containing Constructor objects. If the reflected class represents an interface or a primitive type or there are no public constructors, an array of length zero is returned. The following example enumerates all the constructors of the String class:

Class instance = Class.forName( "java.lang.String" );
Constructor[] result = instance.getConstructors();

for( int i = 0 ; i < result.length ; i++ ) { 
System.out.println( result[i].toString() ); }

This example prints the 11 constructors defined in the String class. See the description of the toString() method in "The Constructor Class," later in this chapter, for details about the formatting of this output.

The getConstructor() Method

Constructor getConstructor(Class[] parameterTypes)

The getConstructor() method returns a single Constructor object that represents the constructor member of the reflected class with a matching signature. The name of the constructor is not specified because this name is always the same as the name of the constructor's class. Only the number, types, and order of the parameters determine which constructor is returned. If a zero-length array of Class objects is sent as a parameter, the default constructor is returned. If no constructor is found within the reflected class, a NoSuchMethodException exception is returned. Interfaces and classes with no public constructors also throw this exception. The following example uses this method to find a specific constructor in the String class:

Class instance = Class.forName("java.lang.String");
Class[] array = new Class[1];
array[0] = Class.forName("java.lang.String");
System.out.println(instance.getConstructor(array).toString());

This program outputs the following line:

public java.langString(java.lang.String)

The getDeclaredClasses() Method

Class[] getDeclaredClasses()

The getDeclaredClasses() method can be used to find the public, private, or protected member classes declared within the reflected class or interface. Inherited member classes are not returned by this method. If the Class object represents a primitive type, or the class declares no classes or interfaces as members, this method returns an array of length zero. The following code is an example of the usage of the getDeclaredClasses() method:

Class instance = Class.forName( "java.net.URLConnection" );
Class[] result = instance.getDeclaredClasses();

The getDeclaredFields() Method

Field[] getDeclaredFields()

Like the getDeclaredClasses() method, the getDeclaredFields() method returns all the private, protected, or public fields declared by the reflected class or interface (excluding inherited methods). If the Class object represents a primitive type or the class declares no fields, this method returns an array of length zero. The following example lists all the declared fields of the URLConnection class:

Class instance = Class.forName( "java.net.URLConnection" );
Field[] result = instance.getDeclaredFields();
for( int i = 0 ; i < result.length ; i++ ) { 
System.out.println( result[i].toString() ); }

The getDeclaredMethods() Method

Method[] getDeclaredMethods()

The getDeclaredMethods() method returns all the private, protected, or public methods of the reflected class or interface (excluding inherited methods). If the Class object represents a primitive type or the class declares no fields, this method returns an array of length zero. The following example lists all the declared methods within the URLConnection class:

Class instance = Class.forName( "java.net.URLConnection" );
Field[] result = instance.getDeclaredFields();
for( int i = 0 ; i < result.length ; i++ ) { 
System.out.println( result[i].toString() ); }

The Member Interface

The Member interface defines a number of methods implemented by the Field, Method, and Constructor classes. Because all these classes are members of classes or interfaces, it is logical that they share some functionality. A detailed explanation of the functionality of these methods is included in this section rather than in each of the classes that implement these member interfaces. Examples of the use of these methods and brief descriptions of their functionality are included in each of the classes that implement the Member interface. Following is a list of the methods defined by the Member interface:

  • Class getDeclaringClass()

  • String getName()

  • int getModifiers()

The getDeclaringClass() Method

Class getDeclaringClass()

The getDeclaringClass() method returns a Class object that represents the class or interface that declared this member. This method is typically used after the getFields(), getMethods(), or getConstructors() method has returned an array of one of the Field, Method, or Constructor classes. Because these methods return member types from superclasses or superinterfaces, getDeclaringClass() is required to determine the class to which a member field, method, or constructor belongs.

The getName() Method

String getName()

The getName() method returns a String indicating the name of this member or constructor.

The getModifiers() Method

int getModifiers()

The getModifiers() method returns the modifiers for the reflected member or constructor. The int returned is an encoded representation of some combination of modifiers in a standard order. The Java virtual machine stores modifiers internally in the same format (that is, as encoded ints). The static toString() method of the Modifier class can be used to translate an encoded int into a string of modifiers.

The Field class

The Field class provides access to the fields of a class or object. The term field refers to both instance and class variables. The Field object is typically used to get a field or set a field. This list shows the member methods of the Field class:

  • Class getDeclaringClass()

  • String getName()

  • int getModifiers()

  • Class getType()

  • boolean equals(Object obj)

  • String toString()

  • Object get(Object obj)

  • boolean getBoolean(Object obj)

  • byte getByte(Object obj)

  • char getChar(Object obj)

  • short getShort(Object obj)

  • int getInt(Object obj)

  • long getLong(Object obj)

  • float getFloat(Object obj)

  • double getDouble(Object obj)

  • int hashCode()

  • void set(Object obj, Object value)

  • void setBoolean(Object obj, boolean z)

  • void setByte(Object obj, byte b)

  • void setChar(Object obj, char c)

  • void setShort(Object obj, short s)

  • void setInt(Object obj, int i)

  • void setLong(Object obj, long l)

  • void setFloat(Object obj, float f)

  • void setDouble(Object obj, double d)

The getDeclaringClass() Method

Class getDeclaringClass()

The getDeclaringClass() method returns an instance of Class to which the instance or class variable represented by the Field object belongs. If an array of Field objects is received in response to a call to the getFields() method of the Class class, the getDeclaringClass() method can be used to find the declaring class for a particular Field object. For example, if you want to find the Class of the third element of an array of Field objects defined within the Panel class and its superclasses, you can use the getDeclaringClass() method in this way:

Class instance = Class.forName( "java.awt.Panel" );
Field[] result = instance.getFields();
System.out.println( result[2].getDeclaringClass().toString() );

The output from this example is as follows:

interface java.awt.image.ImageObserver

The method did not return a Class object representing the Panel class as you may have expected. Instead, it returned an interface-type class called ImageObserver from the image subpackage of java.awt because the getFields() method also returns public fields from the superclass of the reflected class.

The getName() Method

String getName()

The getName() method returns the name of the instance or class variable represented by this Field object. This example demonstrates the use of getName():

System.out.println( result[2].getName() );

If we add this line to the example from the description of getDeclaringClass() in the preceding section, the output includes a second line: PROPERTIES. PROPERTIES is the name of the public instance variable contained in the third element of the array of Field objects.

The getModifiers() Method

int getModifiers()

The getModifiers() method returns an int value that represents the set of modifiers found in the definition of the field represented by the Field object. This example demonstrates the use of the getModifiers() method:

Class instance = Class.forName("java.awt.Event");
Field field = instance.getField("id");
System.out.println(Modifier.toString(field.getModifiers()));

Because the instance variable of class java.awt.Event is public, this example results in the following output:

public

The getType() Method

Class getType()

The getType() method returns the type of field represented by the Field object as a Class object. The following example demonstrates the use of this method on a Field object:

Class instance = Class.forName("java.awt.Event");
Field field = instance.getField("id");
System.out.println( field.getType().toString() );

In this example, the Field object represents the instance variable "id" of class java.awt.Event. Because its type is int, this code outputs the string "int".

The hashCode() Method

int hashCode()

The hashCode() method returns an integer representation of the class created by taking the exclusive-OR of the hashcode of the declaring class and the name of the field represented by this Field object. The following example returns the hashcode for the id field in the Event class:

Class class = Class.forName("java.awt.Event");
Field field = class.getField("id");
System.out.println( field.hashCode() );

The equals() Method

boolean equals(Object obj)

The equals() method compares two Field objects for equality. The two objects are equal and the method returns true if they both have the same declaring class and the same name. The following example shows a case in which two Field objects are defined within the class Event. Because they both exist in the same class, they cannot be equal.

Class instance = Class.forName( "java.awt.Event" );
Field[] result = instance.getFields();
System.out.println( result[2].equals( result[3]  ) );

This code outputs false because these two modifiers do not have the same name.

The toString() Method

String toString()

The toString() method overrides the Object class toString() method. The string returned from this method includes all the modifiers that describe the field represented by the Field object. The modifiers are followed by the return type, package name, and class. The name of the instance variable or class variable is then appended to the end of the class. In this example, the toString() method is called on the second element of the array of Field objects from the Event class:

Class instance = Class.forName( "java.awt.Event" );
Field[] result = instance.getFields();
System.out.println( result[2].toString()  );

The following output is printed:

public final static int java.awt.image.ImageObserver.PROPERTIES

In general, this method first outputs the modifier public, protected, or private, then outputs static, final, transient, or volatile, and finally outputs the type. The modifiers are followed by the fully qualified class name, a period (.), and the name of the field represented by the Field object.

The get(), getBoolean(), getByte(), getChar(), getShort(), getInt(), getLong(), getFloat(), and getDouble() Methods

Object get(Object obj)
boolean getBoolean(Object obj)
byte getByte(Object obj)
char getChar(Object obj)
short getShort(Object obj)
int getInt(Object obj)
long getLong(Object obj)
float getFloat(Object obj)
double getDouble(Object obj)

You can use the get() method to get the value of the instance or class variable represented by a Field object. The Object argument of this method specifies the object from which the value should be taken. The first method always returns a reference to an Object. If the field value contains a primitive type, that type is turned into a reference using an appropriate type wrapper class. The remaining get methods return specific primitive types without wrapping the primitive type. For this reason, they operate more efficiently than the get() method when returning a primitive type.

Java access rules still control access to instance variables. Private variables remain private to an object. If an attempt to access a nonaccessible instance or class variable is made, the get() method throws an IllegalAccessException exception.

In the following example, a value is retrieved from an object of class Button:

Class instance = Class.forName( "java.awt.Button" );
Field result = instance.getField("label");
Button button = new Button("This is a label.");
System.out.println( result.get( button ) );

This example prints the following output:

This is a label

Because the label field of the Button class is protected, the preceding code has to be declared as part of the java.awt package to avoid throwing an IllegalAccessException. If the field is public rather than protected, this is not a concern.

The set(), setBoolean(), setByte(), setChar(), setShort(), setInt(), setLong(), setFloat(), and setDouble() Methods

Object set(Object obj, Object value)
void setBoolean(Object obj, boolean z)
void setByte(Object obj, byte b)
void setChar(Object obj, char c)
void setShort(Object obj, short s)
void setInt(Object obj, int i)
void setLong(Object obj, long l)
void setFloat(Object obj, float f)
void setDouble(Object obj, double d)

The set() method can be used to set the value of an instance variable or class variable represented by the Field object. A value is set within the object specified by the Object argument. The set() method takes a reference to an object as its second parameter; the remaining methods take one of the primitive types as their second parameter. As is true with the get methods, the set methods that return a specific primitive type operate more efficiently than the set() method itself because they do not take the extra step of unwrapping the value to be set when dealing with primitive types. The following example shows how the label field of the Button class can be set within an instance of that class:

Class instance = Class.forName( "java.awt.Button" );
Field result = instance.getDeclaredField("label");
Button button = new Button("This is a label.");
result.set(button,"This is a set label");
System.out.println( result.get( button ) );

In this example, a Field object representing the field label is returned using the getDeclaredField() method. The getField() method would not work in this case because the instance variable is protected. In addition, to gain access to the label field, this code segment must declare itself as part of the java.awt package. After the Field object is created, a new instance of Button is created. The set() method sets the label field of this object to a new value by passing a reference to the Button object as the first parameter and the new value as the second parameter. In a call to the set() method, if the second value happens to be an object of some primitive type, the object is automatically unwrapped. The new value in the label field is then printed by accessing the Field object with the get() method. The example prints the following line:

This is a set label

The Method Class

The Method class provides access to a method of a class or interface. The method represented by the Method object can be an abstract, static, or instance method. As with the Field and Class classes, instances of the Method class can be created only by the Java virtual machine; these instances are always final. The Method object can be used to get information about the reflected method; the Method object can also be used to invoke that method on an instance of the declaring class. All the methods of the Method class are listed here:

  • Class getDeclaringClass()

  • String getName()

  • int getModifiers()

  • Class getReturnType()

  • Class[] getParameterTypes()

  • Class[] getExceptionTypes()

  • boolean equals(Object obj)

  • int hashCode()

  • String toString()

  • Object invoke(Object obj, Object[] args)

The getDeclaringClass() Method

Class getDeclaringClass()

The getDeclaringClass() method returns a Class object that represents the class in which the reflected method is declared. This method can be used as in this example:

Class instance = Class.forName("java.lang.String");
Class[] array = new Class[2];
array[0] = Class.forName("java.lang.String");
array[1] = Integer.TYPE;
Method method = instance.getMethod("indexOf",array);
System.out.println(method.getDeclaringClass().getName());

In this example, getDeclaringClass() returns a Class object representing the declaring class for the indexOf(String, int) method of the String class. The name of the class is printed as output:

java.lang.String


NOTE: The first four lines of code in the preceding example are used in the descriptions of the rest of the methods of the Method class.

The getName() Method

String getName()

The getName() method returns the name of the reflected method as a string. The getName() method can be used as follows:

System.out.println( method.getName() );

If the variable method reflects the indexOf(String, int) method of the String class (refer back to the getDeclaringClass() example), this code segment prints the name of the method:

indexOf

The getModifiers() Method

int getModifiers()

The getModifiers() method returns an int representing the set of modifiers that belongs to the reflected method. This method can be used in the following way:

System.out.println(Modifier.toString(method.getModifiers()));

If the variable method reflects the indexOf(String, int) method of the String class (refer back to the getDeclaringClass() example), this code segment prints the modifiers of this method:

public

The getReturnType() Method

Class getReturnType()

The getReturnType() method returns a Class object representing the return type for the reflected method. The following example demonstrates how this method can be used:

System.out.println(method.getReturnType().toString());

If the variable method reflects the indexOf(String, int) method of the String class (refer back to the getDeclaringClass() example), this code segment prints the return type of this method:

int

The getParameterTypes() Method

Class[] getParameterTypes()

The getParameterTypes() method returns an array of Class objects that represent the order and types of the parameters in the reflected method. The method is used as follows:

Class[] params = method.getParameterTypes();
for(int c=0;c<params.length;c++)
{System.out.println(params[c].toString());}

If the variable method reflects the indexOf(String, int) method of the String class (refer back to the getDeclaringClass() example), this code segment prints the parameter types of this method in the correct order:

class java.lang.String

int

The getExceptionTypes() Method

Class[] getExceptionTypes()

The getExceptionTypes() method returns an array of Class objects that represent the exceptions thrown by the reflected method. This method can be used as follows:

Class[] params = method.getExceptionTypes();
for(int c=0;c<params.length;c++)
{System.out.println(params[c].toString());}

If the variable method reflects the indexOf(String, int) method of the String class (refer back to the getDeclaringClass() example), this code segment prints nothing because the reflected method throws no exceptions and an array of length zero is returned from the getParameterTypes() method.

The equals() Method

boolean equals(Object obj)

The equals() method tests two Method objects for equality. Two Method objects are equal if they have the same declaring class, name, and formal parameter types.

The hashCode() Method

int hashCode()

The hashCode() method returns a hashcode for the reflected method. The hashcode is an exclusive-OR of the hashcodes of the reflected method's declaring class and the reflected method's name. The following example demonstrates how this method can be used:

System.out.println( method.hashCode() );

If the variable method reflects the indexOf(String, int) method of the String class (refer back to the getDeclaringClass() example), this code segment prints the following:

74190650

The toString() Method

String toString()

The toString() method returns a string representation of the reflected field with modifiers, return type, package name, method name, and parameters.

In general, this method first outputs the modifier public, protected, or private, then outputs static, final, transient, or volatile, and finally outputs the return type. The modifiers are followed by a fully qualified class name, a period (.), and the name of the method represented by this Method object. A set of parentheses at the end encloses a list of fully qualified type names representing the methods parameter list. Finally, the word throws is tacked on to the end with a comma-separated list of all the exceptions thrown by this method. The following example shows how the toString() method can be used:

System.out.println( method.toString() );

If the variable method reflects the indexOf(String, int) method of the String class (refer back to the getDeclaringClass() example), this code segment prints this line:

public int java.lang.String.indexOf(java.lang.String, int)

The invoke() Method

Object invoke(Object obj, Object[] args)

The invoke() method is used to call a method on an object. The object name is passed as the first parameter to the method. The second parameter is an array with the arguments to be sent to the method. The following example shows how this method is used:

String string = new String("The day's soma ration");
Object[] arguments = { "soma", new Integer(0) };
System.out.println(method.invoke(string,arguments));

If the variable method reflects the indexOf(String, int) method of the String class (refer back to the getDeclaringClass() example), this code segment prints 10 because the word soma is found at position 10 in the string The day's soma ration.

The Constructor Class

The Constructor class provides access to a constructor of a class. Instances of the Constructor class can be created only by the Java virtual machine; these instances are always final. The Constructor object can be used to get information about the reflected constructor or to create new instances of the declaring class. All the methods of the Constructor class are listed here:

  • Class getDeclaringClass()

  • String getName()

  • int getModifiers()

  • Class[] getParameterTypes()

  • Class[] getExceptionTypes()

  • boolean equals(Object obj)

  • int hashCode()

  • String toString()

  • Object newInstance(Object initargs[])

The getDeclaringClass() Method

Class getDeclaringClass()

The getDeclaringClass() method returns a Class object representing the class in which the reflected constructor is declared. This method can be used as follows:

Class instance = Class.forName("java.lang.String");
Constructor[] constructors = instance.getConstructors();
System.out.println(constructors[0].getDeclaringClass().getName());

In this example, the getDeclaringClass() method is called on the first Constructor object in the array. The getName() method of the Class object name returns java.lang.String.


NOTE: The first two lines of code in this example are used in the descriptions of the rest of the methods of the Constructor class.

The getName() Method

String getName()

The getName() method returns the name of the constructor reflected by the Constructor object. This is the same name as the declaring class. The getName() method in the following example returns the string java.lang.String:

Class instance = Class.forName("java.lang.String");
Constructor[] constructors = instance.getConstructors();
System.out.println(constructors[0].getName());

The getModifiers() Method

int getModifiers()

The getModifiers() method returns an int that represents the modifiers for the constructor reflected by this Constructor object. The following example prints public as the modifier for the first constructor from the java.lang.String class:

Class instance = Class.forName("java.lang.String");
Constructor[] constructors = instance.getConstructors();
System.out.println(Modifier.toString(constructors[0].getModifiers()));

The getParameterTypes() Method

Class[] getParameterTypes()

The getParameterTypes() method returns an ordered list of all the parameters of a constructor in an array of Class objects. The following example shows how the getParameterTypes() method is used:

Class instance = Class.forName("java.lang.String");
Constructor[] constructors = instance.getConstructors();
Class[] parameters = constructors[1].getParameterTypes();
System.out.println(parameters[0].getName());

The only parameter in the second constructor in the String class is a String parameter type. This method prints the following output:

java.lang.String

The getExceptionTypes() Method

Class[] getExceptionTypes()

The getExceptionTypes() method returns an array of Class objects that represent the exceptions thrown by the reflected constructor. This method is used as follows:

System.out.println(constructor.getExceptionTypes());

The equals() Method

boolean equals(Object obj)

The equals() method returns true if the Constructor objects are equal; that is, if they have the same declaring class and the same parameter types, order, and number. The method is used as follows:

System.out.println(constructor1.equals(constructor2));

This example outputs true if constructor1 and constructor2 meet the conditions for equality. If not, the method outputs false.

The hashCode() Method

int hashCode()

The hashCode() method overrides the hashCode() method defined in class Object and returns a hashcode. The returned hashcode is the same as the hashcode of the declaring class. This method is used as shown here:

System.out.println(constructor1.hashCode());

This example prints the hashcode representing the constructor1 Constructor object.

The toString() Method

String toString()

The toString() method returns a string representation of the constructor reflected by this Constructor object. An example of the use and format of the output string is shown here:

Class instance = Class.forName("java.lang.String");
Constructor[] constructors = instance.getConstructors();
System.out.println(constructors[0].toString());

This example sends the following output:

public java.lang.String()

In general, this method first outputs the modifier public, protected, or private, and then outputs static, final, transient, or volatile. The modifiers are followed by a fully qualified class name, a period (.), and the name of the method represented by this Method object. A set of parentheses at the end encloses a list of fully qualified type names representing the method's parameter list. Finally, the word throws is tacked on to the end with a comma-separated list of all the exceptions thrown by this method.

The newInstance() Method

public Object newInstance(Object initargs[]))

The newInstance() method can be used to create a new instance of the Constructor object's declaring class. The method cannot instantiate instances of abstract classes or create a new instance with a constructor that has been declared private. The new object is returned if the number of the arguments match.

Class instance = Class.forName("java.lang.String");
Constructor[] constructors = instance.getConstructors();
Object[] arguments = { "We made a new object!" };
String newObject = (String)constructors[1].newInstance(arguments);
System.out.println( newObject );

In the preceding example, all the constructors that belong to class String are stored in the array constructors. The second array element (at index 1) contains the String constructor that takes a string argument. To instantiate the new object, the arguments must be specified in an array of type Object[]. The first element of this array is set to the string that is used to construct the new String class. Finally, the new instance is created by calling the newInstance() method of the appropriate constructor object; the result is stored in the identifier newObject. This is a convoluted way to send the following output:

We made a new object!

The Array Class

The Array class provides access to array objects and classes. The following methods can be used to instantiate new array objects and to access or modify elements within arrays:

  • Object newInstance(Class componentType, int length)

  • int getLength(Object array)

  • int get(Object array, int index)

  • boolean getBoolean(Object array, int index)

  • byte getByte(Object array, int index)

  • char getChar(Object array, int index)

  • short getShort(Object array, int index)

  • int getInt(Object array, int index)

  • long getLong(Object array, int index)

  • float getFloat(Object array, int index)

  • double getDouble(Object array, int index)

  • void set(Object array, int index, Object value)

  • void setBoolean(Object array, int index, boolean z)

  • void setByte(Object array, int index, byte b)

  • void setChar(Object array, int index, char c)

  • void setShort(Object array, int index, short s)

  • void setInt(Object array, int index, int i)

  • void setLong(Object array, int index, long l)

  • void setFloat(Object array, int index, float f)

  • void setDouble(Object array, int index, double d)

The newInstance() Methods

Object newInstance(Class componentType, int length)
Object newInstance(Class componentType, int[] dimensions)

The newInstance() methods return arrays with the specified component type and dimensions. The first version of the method returns a single dimensional array whose length is specified by the second argument. The second version of the method returns a multidimensional array whose dimensions are specified by the second array argument.

Both methods return an array just as if it had been created in the standard way:

new int[dimensions]
new int[dimensions][dimensions]

In the following example, a new four-element array of type String[] is created using the Array class's newInstance() method. The elements of the array are then initialized and concatenated in a print statement:

String[] strings = (String[])Array.newInstance(Class.forName("java.lang.String"),4);
strings[0] = "I ";
strings[1] = "am ";
strings[2] = "human ";
strings[3] = "not an array! ";
System.out.println( strings[0] + strings[1] + strings[2] + strings[3] );

The output from this example is shown here:

I am human not an array!

Notice that the returned type had to be cast as type String[] because the method returns an array of type Object. If the array has to be multidimensional, you can send an array of ints as the second argument to the newInstance() method.

The getLength() Method

int getLength(Object array)

The getLength() method returns the length of the array argument. If getLength() is called on the strings object created in the example in the preceding section, the method would return 4 as the length of the array. The following example shows this usage:

strings.getLength()

The get(), getBoolean(), getByte() , getChar(), getShort(), getInt(), getLong(), getFloat(), and getDouble() Methods

Object get(Object array, int index)
boolean getBoolean(Object array, int index)
byte getByte(Object array, int index)
char getChar(Object array, int index)
short getShort(Object array, int index)
int getInt(Object array, int index)
long getLong(Object array, int index)
float getFloat(Object array, int index)
double getDouble(Object array, int index)

The get methods return a value of the array object argument at the index specified by the int argument. If the type returned is a primitive type, it is wrapped in its corresponding type wrapper class. Because the methods that get a primitive type do not have to wrap the returned primitive type in a type wrapper, they operate more efficiently.

The following example gets the String value from the second element of the strings array created in the example for the newInstance() method, earlier in this section:

System.out.println( (String)Array.get(strings,1) );

The string "am" is printed as the output for this example.

The set(), setBoolean(), setByte(), setChar(), setShort(), setInt(), setLong(), setFloat(), and setDouble() Methods

void set(Object array, int index, Object value)
void setBoolean(Object array, int index, boolean z)
void setByte(Object array, int index, byte b)
void setChar(Object array, int index, char c)
void setShort(Object array, int index, short s)
void setInt(Object array, int index, int i)
void setLong(Object array, int index, long l)
void setFloat(Object array, int index, float f)
void setDouble(Object array, int index, double d)

These methods set a value of the array object argument at the index specified by the int argument. If the value to set is a primitive type, the value sent in must be wrapped in the appropriate type wrapper class. Because the methods that set a primitive type do not have to unwrap the value to be set, they operate more efficiently than the more general set() method.

The following example resets the second element of the strings object created in the example for the newInstance() method, earlier in this section:

Array.set(strings,1,"am not ");
Array.set(strings,3,"but an array! ");
System.out.println( strings[0] + strings[1] + strings[2] + strings[3] );

The Modifier Class

The Modifier class provides a number of static methods that take an integer as their argument. This integer represents an encoded set of variable or method modifiers. The integer is returned from one of the getModifier() methods described earlier in this chapter. The Java virtual machine stores modifiers internally as encoded integers.

The Modifier class methods return a boolean or String. Typically, the modifier is being tested to determine whether it contains a specific modifier, or it is being decoded and returned as a string representation. The following list includes all the member methods of the Modifier class:

  • boolean isPublic(int mod)

  • boolean isPrivate(int mod)

  • boolean isProtected(int mod)

  • boolean isStatic(int mod)

  • boolean isFinal(int mod)

  • boolean isSynchronized(int mod)

  • boolean isVolatile(int mod)

  • boolean isTransient(int mod)

  • boolean isNative(int mod)

  • boolean isInterface(int mod)

  • boolean isAbstract(int mod)

  • String toString(int mod)

These methods test the integer for a modifier of a particular type. For example, the isPublic() method tests the integer argument and returns true if the integer represents a set of modifiers that contains the public modifier.

The toString() method returns a string of the set of modifiers contained by the integer. This method can be used as follows:

Modifier.toString( method.getModifiers() );

In this example, method is an instance of the Method class, and the getModifiers() method returns an int representing the modifiers declared for the reflected method. The method toString() decodes the int representation; it first outputs a string with the modifier public, protected, or private, and then outputs static, final, transient, or volatile. For example, if the method object in the preceding example is declared as private, final, and static, the following string is output:

private static final

Summary

This chapter described the reflection package new to the Java Development Kit version 1.1. If you are using object serialization or are developing JavaBeans components, you will use this package indirectly. If you happen to be developing debuggers or other applications that require runtime information about, and access to, classes and objects, you may use this package directly.

The Field, Method, Constructor, and Array classes provide the core functionality for inspection and modification of classes and objects. These classes can be created only by the Java virtual machine. The Modifier class contains a number of utility methods that allow you to decode the integer representation of a set of modifiers belonging to a field, method, or class.

TOCBACKFORWARDHOME


©Copyright, Macmillan Computer Publishing. All rights reserved.