September 23, 2019
Hot Topics:

Java Reflection in Action, Part 2

  • May 25, 2005
  • By Dr. Ira Forman & Nate Forman
  • Send Email »
  • More Articles »

1.5.1 Representing primitive types

Although primitives are not objects at all, Java uses class objects to represent all eight primitive types. These class objects can be indicated using a class literal when calling methods such as those in table 1. For example, to specify type int, use int.class. Querying the Vector class for its get method can be accomplished with

Method m = Vector.class.getMethod("get", new Class[] {int.class});

A class object that represents a primitive type can be identified using isPrimitive.

The keyword void is not a type in Java; it is used to indicate a method that does not return a value. However, Java does have a class object to represent void. The isPrimitive method returns true for void.class. In section 1.6, we cover introspection on methods. When introspecting for the return type of a method, void.class is used to indicate that a method returns no value.

1.5.2 Representing interfaces

Java also introduces a class object to represent each declared interface. These class objects can be used to indicate parameters of interface type. The addAll method of Vector takes an implementation of the Collection interface as an argument. Querying the Vector class for its addAll method can be written as

Method m = Vector.class.getMethod( "addAll",
                                   new Class[] {Collection.class} );

A class object that represents an interface may be queried for the methods and constants supported by that interface. The isInterface method of Class can be used to identify class objects that represent interfaces.

1.5.3 Representing array types

Java arrays are objects, but their classes are created by the JVM at runtime. A new class is created for each element type and dimension. Java array classes implement both Cloneable and java.io.Serializable.

Class literals for arrays are specified like any other class literal. For instance, to specify a parameter of a single-dimension Object array, use the class literal Object[].class. A query of the Vector class for its copyInto method is written as

Method m = Vector.class.getMethod( "copyInto", new Class[]{Object[].class} );

Class objects that represent arrays can be identified using the isArray method of Class. The component type for an array class can be obtained using getComponentType. Java treats multidimensional arrays like nested single-dimension arrays. Therefore, the line


evaluates to int[].class. Note the distinction between component type and element type. For the array type int[][], the component type is int[] while the element type is int.

Not all Java methods take non-interface, non-array object parameters like setColor from our George example. In many cases, it is important to introspect for methods such as the Vector methods of listing 2. Now that you understand how to introspect for any Java method, let's examine what can be done once a method is retrieved.

1.6 Understanding method objects

Most of the examples over the last few sections have used the identifier Method but not explained it. Method is the type of the result of all of the method queries in table 1. George uses this class in listing 1 to invoke setColor. From this context, it should be no surprise that java.lang.reflect.Method is the class of the metaobjects that represent methods. Table 3 shows some of the methods supported by the metaobject class Method.

Table 3 Methods defined by Method

Method Description
Class getDeclaringClass() Returns the Class object that declared the method represented by this Method object
Class[] getExceptionTypes() Returns an array of Class objects representing the types of the exceptions declared to be thrown by the method represented by this Method object
int getModifiers() Returns the modifiers for the method represented by this Method object encoded as an int
String getName() Returns the name of the method represented by this Method object
Class[] getParameterTypes() Returns an array of Class objects representing the formal parameters in the order in which they were declared
Class getReturnType() Returns the Class object representing the type returned by the method represented by this Method object
Object invoke(Object obj, Object[] args) Invokes the method represented by this Method object on the specified object with the arguments specified in the Object array

Each Method object provides information about a method including its name, parameter types, return type, and exceptions. A Method object also provides the ability to call the method that it represents. For our example, we are most interested in the ability to call methods, so the rest of this section focuses on the invoke method.

1.6.1 Using dynamic invocation

Dynamic invocation enables a program to call a method on an object at runtime without specifying which method at compile time. In section 1.2, George does not know which setColor method to call when he writes the program. His program relies upon introspection to examine the class of a parameter, obj, at runtime to find the right method. As a result of the introspection, the Method representing setColor is stored in the variable method.

Following the introspection in listing 1, setColor is invoked dynamically with this line:

method.invoke(obj, new Object[] {color});

where the variable color holds a value of type Color. This line uses the invoke method to call the setColor method found previously using introspection. The setColor method is invoked on obj and is passed the value of color as a parameter.

The first parameter to invoke is the target of the method call, or the Object on which to invoke the method. George passes in obj because he wants to call setColor (the method represented by method) on obj. However, if setColor is declared static by the class of obj, the first parameter is ignored because static methods do not need invocation targets. For a static method, null can be supplied as the first argument to invoke without causing an exception.

The second parameter to invoke, args, is an Object array. The invoke method passes the elements of this array to the dynamically invoked method as actual parameters. For a method with no parameters, the second parameter may be either a zero-length array or null.

Page 2 of 3

Enterprise Development Update

Don't miss an article. Subscribe to our newsletter below.

Thanks for your registration, follow us on our social networks to keep up-to-date