CoreJava


Java Reflection

 Introduction to Java Reflection
  Classes
  Constructors
  Fields
  Methods
  Getters and Setters
  Private Fields and Methods
  Annotations
  Generics
  Arrays
  Dynamic Proxies
  Dynamic Class Loading and Reloading
What is Reflection ?
Java's Reflection API's makes it possible to inspect classes, interfaces, fields and methods at runtime, without knowing the names of the classes, methods etc. at compile time. It is also possible to instantiate new objects, invoke methods and get/set field values using reflection.

Java Reflection: Classes
Using Java Reflection you can inspect Java classes at runtime. Inspecting classes is often the first thing you do when using Reflection. From the classes you can obtain information about
Class Name
Class Modifies (public, private, synchronized etc.)
Package Info
Super class
Implemented Interfaces
Constructors
Methods
Fields
Annotations
Plus a lot more information related to Java classes. For a full list you should consult the JavaDoc for java.lang.Class.


The Class Object
All types in Java including the primitive types (int, long, float etc.) including arrays have an associated Class object. If you know the name of the class at compile time you can obtain a Class object like this:

    Class myObjectClass = MyObjectClass

If you don't know the name at compile time, but have the class name as a string at runtime, you can do like this:

String className = ... //obtain class name as string at runtime
Class class = Class.forName (className);

When using the Class.forName () method you must supply the fully qualified class name. That is the class name including all package names. For instance, if MyObject is located in package com.jenkov.myapp then the fully qualified class name is com.jenkov.myapp. MyObject

The Class.forName () method may throw a ClassNotFoundException if the class cannot be found on the classpath at runtime.



Class Name
From a Class object you can obtain its name in two versions. The fully qualified class name (including package name) is obtained using the getName () method like this:

    Class aClass = ... //obtain Class object. See prev. section
    String className = aClass. getName ();

If you want the class name without the pacakge name you can obtain it using the getSimpleName () method, like this:

    Class aClass          = ... //obtain Class object. See prev. section
    String simpleClassName = aClass. getSimpleName ();

Modifiers
You can access the modifiers of a class via the Class object. The class modifiers are the keywords "public", "private", "static" etc.
    Class aClass = ... //obtain Class object. See prev. section
    int modifiers = aClass.getModifiers ();
The modifiers are packed into an int where each modifier is a flag bit that is either set or cleared. You can check the modifiers using these methods in the class      java.lang.reflect.Modifier:

    Modifier.isAbstract (int modifiers)
    Modifier.isFinal (int modifiers)
    Modifier.isInterface (int modifiers)
    Modifier.isNative (int modifiers)
    Modifier.isPrivate (int modifiers)
    Modifier.isProtected (int modifiers)
    Modifier.isPublic (int modifiers)
    Modifier.isStatic (int modifiers)
    Modifier.isStrict (int modifiers)
    Modifier.isSynchronized (int modifiers)
    Modifier.isTransient (int modifiers)
    Modifier.isVolatile (int modifiers)

Package Info
You can obtain information about the package from a Class object like this:
Class aClass = ... //obtain Class object. See prev. section
Package package = aClass.getPackage ();
From the Package object you have access to information about the package like its name. You can also access information specified for this package in the Manifest file of the JAR file this package is located in on the classpath. For instance, you can specify package version numbers in the Manifest file. You can read more about the Package class here: java.lang.Package

Superclass
From the Class object you can access the superclass of the class. Here is how:
Class superclass = aClass.getSuperclass ();
The superclass class object is a Class object like any other, so you can continue doing class reflection on that too.

Implemented Interfaces
It is possible to get a list of the interfaces implemented by a given class. Here is how:
Class aClass = ... //obtain Class object. See prev. section
Class [] interfaces = aClass.getInterfaces ();

A class can implement many interfaces. Therefore an array of Class is returned. Interfaces are also represented by Class objects in Java Reflection.

NOTE: Only the interfaces specifically declared implemented by a given class is returned. If a superclass of the class implements an interface, but the class doesn't specifically state that it also implements that interface, that interface will not be returned in the array. Even if the class in practice implements that interface, because the superclass does.

To get a complete list of the interfaces implemented by a given class you will have to consult both the class and its super classes recursively.

Constructors
You can access the constructors of a class like this:
 Constructor [] constructors = aClass.getConstructors ();

Methods
You can access the methods of a class like this:
 Method [] method = aClass.getMethods ();



Fields
You can access the fields (member variables) of a class like this:
 Method [] method = aClass.getFields ();

Annotations
You can access the class annotations of a class like this:
 Annotation [] annotations = aClass.getAnnotations ();

Java Reflection: Constructors

Using Java Reflection you can inspect the constructors of classes and instantiate objects at runtime. This is done via the Java class java.lang.reflect.Constructor. This text will get into more detail about the Java Constructor object. Here is a list of the topics covered:
Obtaining Constructor Objects
Constructor Parameters
Instantiating Objects using Constructor Object


Obtaining Constructor Objects
The Constructor class is obtained from the Class object. Here is an example:
Class aClass = ...//obtain class object
Constructor [] constructors = aClass.getConstructors ();
The Constructor[] array will have one Constructor instance for each public constructor declared in the class.

If you know the precise parameter types of the constructor you want to access, you can do so rather than obtain the array all constructors. This example returns the public constructor of the given class which takes a String as parameter:

Class aClass = ...//obtain class object
Constructor constructor = aClass.getConstructors (new Class []{String. class});

If no constructor matches the given constructor arguments, in this case String. class, a NoSuchMethodException is thrown.

Constructor Parameters
You can read what parameters a given constructor takes like this:
Constructor constructor = ... // obtain constructor - see above
Class [] parameterTypes = constructor.getParameterTypes ();
Instantiating Objects using Constructor Object
You can instantiate an object like this:
//get constructor that takes a String as argument
Constructor constructor = MyObject.class.getConstructor (String. class);
MyObject myObject = (MyObject) constructor.newInstance ("constructor-arg1");

The Constructor.newInstance () method takes an optional amount of parameters, but you must supply exactly one parameter per argument in the constructor you are invoking. In this case it was a constructor taking a String, so one String must be supplied.

 

Java Reflection: Fields

Using Java Reflection you can inspect the fields (member variables) of classes and get / set them at runtime. This is done via the Java class java.lang.reflect.Field. This text will get into more detail about the Java Field object. Here is a list of the topics covered:

Obtaining Field Objects
Field Name
Field Type
Getting and Setting Field Values


Obtaining Field Objects
The Field class is obtained from the Class object. Here is an example:

Class aClass = ...//obtain class object
Field [] field = aClass.getFields ();

The Field [] array will have one Field instance for each public field declared in the class.
If you know the name of the field you want to access, you can access it like this:

Class aClass = MyObject.class
Field field = aClass.getFields ("some Field");

The example above will return the Field instance corresponding to the field some Field as declared in the MyObject below:
public class MyObject{
  public String someField = null;
}
If no field exists with the name given as parameter to the getField () method, a NoSuchFieldException is thrown.

Field Name
Once you have obtained a Field instance, you can get its field name using the Field.getName () method, like this:

Field field = ... //obtain field object
String fieldName = field.getName ();



Field Type
You can determine the field type (String, int etc.) of a field using the Field.getType () method:

Field field = aClass. getField ("someField");
Object fieldType = field.getType ();

Getting and Setting Field Values
Once you have obtained a Field reference you can get and set its values using the Field.get() and Field.set() methods, like this:

Class aClass = MyObject.class
Field field = aClass.getField("someField");

MyObject objectInstance = new MyObject ();

Object value = field.get(objectInstance);

field.set(objetInstance, value);

The objectInstance parameter passed to the get and set method should be an instance of the class that owns the field. In the above example an instance of MyObject is used, because the someField is an instance member of the MyObject class.

It the field is a static field (public static ...) pass null as parameter to the get and set methods, instead of the objectInstance parameter passed above.



Java Reflection: Methods

Using Java Reflection you can inspect the methods of classes and invoke them at runtime. This is done via the Java class java.lang.reflect.Method. Here is a list of the topics covered:

Obtaining Method Objects
Method Parameters and Return Types
Instantiating Objects using Constructor Object

Obtaining Method Objects
The Method class is obtained from the Class object. Here is an example:
Class aClass = ...//obtain class object
Method[] methods = aClass.getMethods();
The Method[] array will have one Method instance for each public method declared in the class.

If you know the precise parameter types of the method you want to access, you can do so rather than obtain the array all methods. This example returns the public method named "doSomething", in the given class which takes a String as parameter:

Class aClass = ...//obtain class object
Method method =    aClass.getMethod("doSomething", new Class[]{String.class});

If no method matches the given method name and arguments, in this case String.class, a NoSuchMethodException is thrown.

If the method you are trying to access takes no parameters, pass null as the parameter type array, like this:

Class aClass = ...//obtain class object
Method method =    aClass.getMethod("doSomething", null);

Method Parameters and Return Types
You can read what parameters a given method takes like this:

Method method = ... // obtain method - see above
Class[] parameterTypes = method.getParameterTypes();

You can access the return type of a method like this:

Method method = ... // obtain method - see above
Class returnType = method.getReturnType();

Invoking Methods using Method Object
You can invoke a method like this:
//get method that takes a String as argument

Method method = MyObject.class.getMethod("doSomething", String.class);
Object returnValue = method.invoke(null, "parameter-value1");

The null parameter is the object you want to invoke the method on. If the method is static you supply null instead of an object instance. In this example, if doSomething(String.class) is not static, you need to supply a valid MyObject instance instead of null;

The Method.invoke(Object target, Object ... parameters) method takes an optional amount of parameters, but you must supply exactly one parameter per argument in the method you are invoking. In this case it was a method taking a String, so one String must be supplied.


Java Reflection: Getters and Setters

Using Java Reflection you can inspect the methods of classes and invoke them at runtime. This can be used to detect what getters and setters a given class has. You cannot ask for getters and setters explicitly, so you will have to scan through all the methods of a class and check if each method is a getter or setter.

First let's establish the rules that characterizes getters and setters:

Getter
A getter method have its name start with "get", take 0 parameters, and returns a value.

Setter
A setter method have its name start with "set", and takes 1 parameter.
Setters may or may not return a value. Some setters return void, some the value set, others the object the setter were called on for use in method chaining. Therefore you should make no assumptions about the return type of a setter.

Here is a code example that finds getter and setters of a class:

public static void printGettersSetters(Class aClass){
  Method[] methods = aClass.getMethods();

  for(Method method : methods){
    if(isGetter(method)) System.out.println("getter: " + method);
    if(isSetter(method)) System.out.println("setter: " + method);
  }
}

public static boolean isGetter(Method method){
  if(!method.getName().startsWith("get"))      return false;
  if(method.getParameterTypes().length != 0)   return false; 
  if(void.class.equals(method.getReturnType()) return false;
  return true;
}

public static boolean isSetter(Method method){
  if(!method.getName().startsWith("set")) return false;
  if(method.getParameterTypes().length != 1) return false;
  return true;
}





Java Reflection: Private Fields and Methods
Despite the common belief it is actually possible to access private fields and methods of other classes via Java Reflection. It is not even that difficult. This can be very handy during unit testing. This text will show you how.
Note: This only works when running the code as a standalone Java application, like you do with unit tests and regular applications. If you try to do this inside a Java Applet, you will need to fiddle around with the SecurityManager. But, since that is not something you need to do very often, it is left out of this text so far.
Here is a list of the topics covered in this text:
  1. Accessing Private Fields
  2. Accessing Private Methods

Accessing Private Fields

To access a private field you will need to call the Class.getDeclaredField(String name) or Class.getDeclaredFields() method. The methods Class.getField(String name) and Class.getFields() methods only return public fields, so they won't work. Here is a simple example of a class with a private field, and below that the code to access that field via Java Reflection:
public class PrivateObject {
  private String privateString = null;
  public PrivateObject(String privateString) {
    this.privateString = privateString;
  }
}
PrivateObject privateObject = new PrivateObject("The Private Value");
 
Field privateStringField = PrivateObject.class.
            getDeclaredField("privateString");
 
privateStringField.setAccessible(true);
 
String fieldValue = (String) privateStringField.get(privateObject);
System.out.println("fieldValue = " + fieldValue);
This code example will print out the text "fieldValue = The Private Value", which is the value of the private field privateString of the PrivateObject instance created at the beginning of the code sample.
Notice the use of the method PrivateObject.class.getDeclaredField("privateString"). It is this method call that returns the private field. This method only returns fields declared in that particular class, not fields declared in any superclasses.
Notice the line in bold too. By calling Field.setAcessible(true) you turn off the access checks for this particular Field instance, for reflection only. Now you can access it even if it is private, protected or package scope, even if the caller is not part of those scopes. You still can't access the field using normal code. The compiler won't allow it.

Accessing Private Methods

To access a private method you will need to call the Class.getDeclaredMethod(String name, Class[] parameterTypes) or Class.getDeclaredMethods() method. The methods Class.getMethod(String name, Class[] parameterTypes) and Class.getMethods() methods only return public methods, so they won't work. Here is a simple example of a class with a private method, and below that the code to access that method via Java Reflection:
public class PrivateObject {
 
  private String privateString = null;
 
  public PrivateObject(String privateString) {
    this.privateString = privateString;
  }
 
  private String getPrivateString(){
    return this.privateString;
  }
}
PrivateObject privateObject = new PrivateObject("The Private Value");
 
Method privateStringMethod = PrivateObject.class.
        getDeclaredMethod("getPrivateString", null);
 
privateStringMethod.setAccessible(true);
 
String returnValue = (String)
        privateStringMethod.invoke(privateObject, null);
    
System.out.println("returnValue = " + returnValue);
This code example will print out the text "returnValue = The Private Value", which is the value returned by the method getPrivateString() when invoked on the PrivateObject instance created at the beginning of the code sample.
Notice the use of the method PrivateObject.class.getDeclaredMethod("privateString"). It is this method call that returns the private method. This method only returns methods declared in that particular class, not methods declared in any superclasses.
Notice the line in bold too. By calling Method.setAcessible(true) you turn off the access checks for this particular Method instance, for reflection only. Now you can access it even if it is private, protected or package scope, even if the caller is not part of those scopes. You still can't access the method using normal code. The compiler won't allow it.

Java Reflection: Annotations

Using Java Reflection you can access the annotations attached to Java classes at runtime. Here is a list of the topics covered in this text:

What are Java Annotations?

Annotations is a new feature from Java 5. Annotations are a kind of comment or meta data you can insert in your Java code. These annotations can then be processed at compile time by pre-compiler tools, or at runtime via Java Reflection. Here is an example of class annotation:
@MyAnnotation(name="someName",  value = "Hello World")
public class TheClass {
}
The class TheClass has the annotation @MyAnnotation written ontop. Annotations are defined like interfaces. Here is the MyAnnotation definition:
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
 
public @interface MyAnnotation {
    public String name();
    public String value();
}
The @ in front of the interface marks it as an annotation. Once you have defined the annotation you can use it in your code, as shown in the earlier examples.
The two directives in the annotation definition, @Retention(RetentionPolicy.RUNTIME) and @Target(ElementType.TYPE), specifies how the annotation is to be used.
@Retention(RetentionPolicy.RUNTIME) means that the annotation can be accessed via reflection at runtime. If you do not set this directive, the annotation will not be preserved at runtime, and thus not available via reflection.
@Target(ElementType.TYPE) means that the annotation can only be used ontop of types (classes and interfaces typically). You can also specify METHOD or FIELD, or you can leave the target out alltogether so the annotation can be used for both classes, methods and fields.

Class Annotations

You can access the annotations of a class, method or field at runtime. Here is an example that accesses the class annotations:
Class aClass = TheClass.class;
Annotation[] annotations = aClass.getAnnotations();
 
for(Annotation annotation : annotations){
    if(annotation instanceof MyAnnotation){
        MyAnnotation myAnnotation = (MyAnnotation) annotation;
        System.out.println("name: " + myAnnotation.name());
        System.out.println("value: " + myAnnotation.value());
    }
}
You can also access a specific class annotation like this:
Class aClass = TheClass.class;
Annotation annotation = aClass.getAnnotation(MyAnnotation.class);
 
if(annotation instanceof MyAnnotation){
    MyAnnotation myAnnotation = (MyAnnotation) annotation;
    System.out.println("name: " + myAnnotation.name());
    System.out.println("value: " + myAnnotation.value());
}

Method Annotations

Here is an example of a method with annotations:
 
 
public class TheClass {
  @MyAnnotation(name="someName",  value = "Hello World")
  public void doSomething(){}
}
You can access method annotations like this:
Method method = ... //obtain method object
Annotation[] annotations = method.getDeclaredAnnotations();
 
for(Annotation annotation : annotations){
    if(annotation instanceof MyAnnotation){
        MyAnnotation myAnnotation = (MyAnnotation) annotation;
        System.out.println("name: " + myAnnotation.name());
        System.out.println("value: " + myAnnotation.value());
    }
}
You can also access a specific method annotation like this:
Method method = ... // obtain method object
Annotation annotation = method.getAnnotation(MyAnnotation.class);
 
if(annotation instanceof MyAnnotation){
    MyAnnotation myAnnotation = (MyAnnotation) annotation;
    System.out.println("name: " + myAnnotation.name());
    System.out.println("value: " + myAnnotation.value());
}
 

Parameter Annotations

It is possible to add annotations to method parameter declarations too. Here is how that looks:
public class TheClass {
  public static void doSomethingElse(
        @MyAnnotation(name="aName", value="aValue") String parameter){
  }
}
You can access parameter annotations from the Method object like this:
Method method = ... //obtain method object
Annotation[][] parameterAnnotations = method.getParameterAnnotations();
Class[] parameterTypes = method.getParameterTypes();
 
int i=0;
for(Annotation[] annotations : parameterAnnotations){
  Class parameterType = parameterTypes[i++];
 
  for(Annotation annotation : annotations){
    if(annotation instanceof MyAnnotation){
        MyAnnotation myAnnotation = (MyAnnotation) annotation;
        System.out.println("param: " + parameterType.getName());
        System.out.println("name : " + myAnnotation.name());
        System.out.println("value: " + myAnnotation.value());
    }
  }
}
Notice how the Method.getParameterAnnotations() method returns a two-dimensional Annotation array, containing an array of annotations for each method parameter.

Field Annotations

Here is an example of a field with annotations:
public class TheClass {
 
  @MyAnnotation(name="someName",  value = "Hello World")
  public String myField = null;
}
You can access field annotations like this:
Field field = ... //obtain field object
Annotation[] annotations = field.getDeclaredAnnotations();
 
for(Annotation annotation : annotations){
    if(annotation instanceof MyAnnotation){
        MyAnnotation myAnnotation = (MyAnnotation) annotation;
        System.out.println("name: " + myAnnotation.name());
        System.out.println("value: " + myAnnotation.value());
    }
}
You can also access a specific field annotation like this:
Field field = ... // obtain method object
Annotation annotation = field.getAnnotation(MyAnnotation.class);
 
if(annotation instanceof MyAnnotation){
    MyAnnotation myAnnotation = (MyAnnotation) annotation;
    System.out.println("name: " + myAnnotation.name());
    System.out.println("value: " + myAnnotation.value());
}

Java Reflection: Generics

I have often read in articles and forums that all Java Generics information is erased at compile time so that you cannot access any of that information at runtime. This is not entirely true though. It is possible to access generics information at runtime in a handful of cases. These cases actually cover several of our needs for Java Generics information. This text explains these cases.

Here is a list of the topics covered in this text:

The Generics Reflection Rule of Thumb
Generic Method Return Type
Generic Method Parameter Types
Generic Field Types


The Generics Reflection Rule of Thumb
Using Java Generics typically falls into one of two different situations:

Declaring a class/interface as being parameterizable.
Using a parameterizable class.
When you write a class or interface you can specify that it should be paramerizable. This is the case with the java.util.List interface. Rather than create a list of Object you can parameterize java.util.List to create a list of say String.

When runtime inspecting a parameterizable type itself, like java.util.List, there is no way of knowing what type is has been parameterized to. This makes sense since the type can be parameterized to all kinds of types in the same application. But, when you inspect the method or field that declares the use of a parameterized type, you can see at runtime what type the paramerizable type was parameterized to. In short:

You cannot see on a type itself what type it is parameterized to a runtime, but you can see it in fields and methods where it is used and parameterized. Its concrete parameterizations in other words.

The following sections take a closer look at these situations.



Generic Method Return Types
If you have obtained a java.lang.reflect.Method object it is possible to obtain information about its generic return type. This cannot be any of the Method objects in the parameterized type, but in the class that uses the parameterized type. You can read how to obtain Method objects in the text "Java Generics: Methods". Here is an example class with a method having a parameterized return type:

public class MyClass {

  protected List<String> stringList = ...;

  pulic List<String> getStringList(){
    return this.stringList;
  }
}

In this class it is possible to obtain the generic return type of the getStringList() method. In other words, it is possible to detect that getStringList() returns a List<String> and not just a List. Here is how:

Method method = MyClass.class.getMethod("getStringList", null);

Type returnType = method.getGenericReturnType();

if(returnType instanceof ParameterizedType){
    ParameterizedType type = (ParameterizedType) returnType;
    Type[] typeArguments = type.getActualTypeArguments();
    for(Type typeArgument : typeArguments){
        Class typeArgClass = (Class) typeArgument;
        System.out.println("typeArgClass = " + typeArgClass);
    }
}

This piece of code will print out the text "typeArgClass = java.lang.String". The Type[] array typeArguments array will contain one item - a Class instance representing the class java.lang.String. Class implements the Type interface.



Generic Method Parameter Types
You can also access the generic types of parameter types at runtime via Java Reflection. Here is an example class with a method taking a parameterized List as parameter:

public class MyClass {
  protected List<String> stringList = ...;

  pulic void setStringList(List<String> list){
    this.stringList = list;
  }
}

You can access the generic parameter types of the method parameters like this:

method = Myclass.class.getMethod("setStringList", List.class);

Type[] genericParameterTypes = method.getGenericParameterTypes();

for(Type genericParameterType : genericParameterTypes){
    if(genericParameterType instanceof ParameterizedType){
        ParameterizedType aType = (ParameterizedType) genericParameterType;
        Type[] parameterArgTypes = aType.getActualTypeArguments();
        for(Type parameterArgType : parameterArgTypes){
            Class parameterArgClass = (Class) parameterArgType;
            System.out.println("parameterArgClass = " + parameterArgClass);
        }
    }
}

This code will print out the text "parameterArgType = java.lang.String". The Type[] array parameterArgTypes array will contain one item - a Class instance representing the class java.lang.String. Class implements the Type interface.



Generic Field Types
It is also possible to access the generic types of public fields. Fields are class member variables - either static or instance variables. You can read about obtaining Field objects in the text "Java Generics: Fields". Here is the example from earlier, with an instance field called stringList.

public class MyClass {
  public List<String> stringList = ...;
}

Field field = MyClass.class.getField("stringList");

Type genericFieldType = field.getGenericType();
   
if(genericFieldType instanceof ParameterizedType){
    ParameterizedType aType = (ParameterizedType) genericFieldType;
    Type[] fieldArgTypes = aType.getActualTypeArguments();
    for(Type fieldArgType : fieldArgTypes){
        Class fieldArgClass = (Class) fieldArgType;
        System.out.println("fieldArgClass = " + fieldArgClass);
    }
}

This code will print out the text "fieldArgClass = java.lang.String". The Type[] array fieldArgTypes array will contain one item - a Class instance representing the class java.lang.String. Class implements the Type interface.


Java Reflection: Arrays

Working with arrays in Java Reflection can be a bit tricky at times. Especially if you need to obtain the Class object for a certain type of array, like int[] etc. This text will discuss how to both create arrays and get their class objects via Java Reflection.

Note: This text has been updated after reading Eyal Lupu's blog post
"Two Side Notes About Arrays and Reflection" which commented on the first edition of this text. The current edition takes his comments into consideration.

Here is a list of the topics covered:

java.lang.reflect.Array
Creating Arrays
Accessing Arrays
Obtaining the Class Object of an Array
Obtaining the Component Type of an Array


java.lang.reflect.Array
Working with arrays via Java Reflection is done using the java.lang.reflect.Array class. Do not confuse this class with the java.util.Arrays class in the Java Collections suite, which contains utility methods for sorting arrays, converting them to collections etc.



Creating Arrays
Creating arrays via Java Reflection is done using the java.lang.reflect.Array class. Here is an example showing how to create an array:

int[] intArray = (int[]) Array.newInstance(int.class, 3);

This code sample creates an array of int. The first parameter int.class given to the Array.newInstance() method tells what type each element in the array should be of. The second parameter states how many elements the array should have space for.



Accessing Arrays
It is also possible to access the elements of an array using Java Reflection. This is done via the Array.get(...) and Array.set(...) methods. Here is an example:

int[] intArray = (int[]) Array.newInstance(int.class, 3);

Array.set(intArray, 0, 123);
Array.set(intArray, 1, 456);
Array.set(intArray, 2, 789);

System.out.println("intArray[0] = " + Array.get(intArray, 0));
System.out.println("intArray[1] = " + Array.get(intArray, 1));
System.out.println("intArray[2] = " + Array.get(intArray, 2));

This code sample will print out this:

intArray[0] = 123
intArray[1] = 456
intArray[2] = 789



Obtaining the Class Object of an Array
One of the problems I ran into when implementing the script language in Butterfly DI Container was how to obtain the Class object for arrays via Java Reflection. Using non-reflection code you can do like this:

Class stringArrayClass = String[].class;

Doing this using Class.forName() is not quite straightforward. For instance, you can access the primitive int array class object like this:

Class intArray = Class.forName("[I");

The JVM represents an int via the letter I. The [ on the left means it is the class of an int array I am interested in. This works for all other primitives too.

For objects you need to use a slightly different notation:

Class stringArrayClass = Class.forName("[Ljava.lang.String;");

Notice the [L to the left of the class name, and the ; to the right. This means an array of objects with the given type.

As a side note, you cannot obtain the class object of primitives using Class.forName(). Both of the examples below result in a ClassNotFoundException:

Class intClass1 = Class.forName("I");
Class intClass2 = Class.forName("int");

I usually do something like this to obtain the class name for primitives as well as objects:

public Class getClass(String className){
  if("int" .equals(className)) return int .class;
  if("long".equals(className)) return long.class;
  ...
  return Class.forName(className);
}

Once you have obtained the Class object of a type there is a simple way to obtain the Class of an array of that type. The solution, or workaround as you might call it, is to create an empty array of the desired type and obtain the class object from that empty array. It's a bit of a cheat, but it works. Here is how that looks:

Class theClass = getClass(theClassName);
Class stringArrayClass = Array.newInstance(theClass, 0).getClass();

This presents a single, uniform method to access the array class of arrays of any type. No fiddling with class names etc.

To make sure that the Class object really is an array, you can call the Class.isArray() method to check:

Class stringArrayClass = Array.newInstance(String.class, 0).getClass();
System.out.println("is array: " + stringArrayClass.isArray());



Obtaining the Component Type of an Array
Once you have obtained the Class object for an array you can access its component type via the Class.getComponentType() method. The component type is the type of the items in the array. For instance, the component type of an int[] array is the int.class Class object. The component type of a String[] array is the java.lang.String Class object.

Here is an example of accessing the component type array:

String[] strings = new String[3];
Class stringArrayClass = strings.getClass();
Class stringArrayComponentType = stringArrayClass.getComponentType();
System.out.println(stringArrayComponentType);

This example will print out the text "java.lang.String" which is the component type of the String array.




Java Reflection: Dynamic Proxies

Using Java Reflection you create dynamic implementations of interfaces at runtime. You do so using the class java.lang.reflect.Proxy. The name of this class is why I refer to these dynamic interface implementations as dynamic proxies. Dynamic proxies can be used for many different purposes, e.g. database connection and transaction management, dynamic mock objects for unit testing, and other AOP-like method intercepting purposes.

Here is a list of topics covered in this text on dynamic proxies:

Creating Proxies
InvocationHandler's
Known Use Cases


Creating Proxies
You create dynamic proxies using the Proxy.newProxyInstance() method. The newProxyInstance() methods takes 3 parameters:

The ClassLoader that is to "load" the dynamic proxy class.
An array of interfaces to implement.
An InvocationHandler to forward all methods calls on the proxy to.
Here is an example:

InvocationHandler handler = new MyInvocationHandler();
MyInterface proxy = (MyInterface) Proxy.newProxyInstance(
                            MyInterface.class.getClassLoader(),
                            new Class[] { MyInterface.class },
                            handler);

After running this code the proxy variable contains a dynamic implementation of the MyInterface interface. All calls to the proxy will be forwarded to the handler implementation of the general InvocationHandler interface. InvocationHandler's are covered i the next section.



InvocationHandler's
As mentioned earlier you must pass an InvocationHandler implementation to the Proxy.newProxyInstance() method. All method calls to the dynamic proxy are forwarded to this InvocationHandler implementation. Here is how the InvocationHandler interface looks:

public interface InvocationHandler{
  Object invoke(Object proxy, Method method, Object[] args)
         throws Throwable;
}

Here is an example implementation:

public class MyInvocationHandler implements InvocationHandler{

  public Object invoke(Object proxy, Method method, Object[] args)
  throws Throwable {
    //do something "dynamic"
  }
}

The proxy parameter passed to the invoke() method is the dynamic proxy object implementing the interface. Most often you don't need this object.

The Method object passed into the invoke() method represents the method called on the interface the dynamic proxy implements. From the Method object you can obtain the method name, parameter types, return type, etc. See the text on Methods for more information.

The Object[] args array contains the parameter values passed to the proxy when the method in the interface implemented was called. Note: Primitives (int, long etc) in the implemented interface are wrapped in their object counterparts (Integer, Long etc.).



Known Use Cases
Dynamic proxies are known to be used for at least the following purposes:

Database Connection and Transaction Management
Dynamic Mock Objects for Unit Testing
Adaptation of DI Container to Custom Factory Interfaces
AOP-like Method Interception


Database Connection and Transaction Management
The Spring framework has a transaction proxy that can start and commit / rollback a transaction for you. How this works is described in more detail in the text Advanced Connection and Transaction Demarcation and Propagation , so I'll only describe it briefly. The call sequence becomes something along this:

web controller --> proxy.execute(...);
  proxy --> connection.setAutoCommit(false);
  proxy --> realAction.execute();
    realAction does database work
  proxy --> connection.commit();



Dynamic Mock Objects for Unit Testing
The Butterfly Testing Tools makes use of dynamic proxies to implement dynamic stubs, mocks and proxies for unit testing. When testing a class A that uses another class B (interface really), you can pass a mock implementation of B into A instead of a real B. All method calls on B are now recorded, and you can set what return values the mock B is to return.

Furthermore Butterfly Testing Tools allow you to wrap a real B in a mock B, so that all method calls on the mock are recorded, and then forwarded to the real B. This makes it possible to check what methods were called on a real functioning B. For instance, if testing a DAO you can wrap the database connection in a mock. The DAO will not see the difference, and the DAO can read/write data to the database as usual since the mock forwards all calls to the database. But now you can check via the mock if the DAO uses the connection properly, for instance if the connection.close() is called (or NOT called), if you expected that. This is normally not possible to determine from the return value of a DAO.



Adaptation of DI Container to Custom Factory Interfaces
The dependency injection container Butterfly Container has a powerful feature that allows you to inject the whole container into beans produced by it. But, since you don't want a dependency on the container interface, the container is capable of adapting itself to a custom factory interface of your design. You only need the interface. No implementation. Thus the factory interface and your class could look something like this:

public interface IMyFactory {
  Bean   bean1();
  Person person();
  ...
}

public class MyAction{

  protected IMyFactory myFactory= null;

  public MyAction(IMyFactory factory){
    this.myFactory = factory;
  }

  public void execute(){
    Bean bean = this.myFactory.bean();
    Person person = this.myFactory.person();
  }

}

When the MyAction class calls methods on the IMyFactory instance injected into its constructor by the container, the method calls are translated into calls to the IContainer.instance() method, which is the method you use to obtain instances from the container. That way an object can use Butterfly Container as a factory at runtime, rather than only to have dependencies injected into itself at creation time. And this without having any dependencies on any Butterfly Container specific interfaces.



AOP-like Method Interception
The Spring framework makes it possible to intercept method calls to a given bean, provided that bean implements some interface. The Spring framework wraps the bean in a dynamic proxy. All calls to the bean are then intercepted by the proxy. The proxy can decide to call other methods on other objects either before, instead of, or after delegating the method call to the bean wrapped.

Dynamic Class Loading and Reloading in Java

It is possible to load and reload classes at runtime in Java, though it is not as straightforward as one might have hoped. This text will explain when and how you can load and reload classes in Java.

You can argue whether Java's dynamic class loading features are really part of Java Reflection, or a part of the core Java platform. Anyways, the article has been put in the Java Reflection trail in lack of a better place to put it.

Here is a list of the topics covered in this text:

The ClassLoader
The ClassLoader Hierarchy
Class Loading
Dynamic Class Loading
Dynamic Class Reloading
Designing your Code for Class Reloading
ClassLoader Load / Reload Example


The ClassLoader
All classes in a Java application are loaded using some subclass of java.lang.ClassLoader. Loading classes dynamically must therefore also be done using a java.lang.ClassLoader subclass.

When a class is loaded, all classes it references are loaded too. This class loading pattern happens recursively, until all classes needed are loaded. This may not be all classes in the application. Unreferenced classes are not loaded until the time they are referenced.



The ClassLoader Hierarchy
Class loaders in Java are organized into a hierarchy. When you create a new standard Java ClassLoader you must provide it with a parent ClassLoader. If a ClassLoader is asked to load a class, it will ask its parent class loader to load it. If the parent class loader can't find the class, the child class loader then tries to load it itself.



Class Loading
The steps a given class loader uses when loading classes are:

Check if the class was already loaded.
If not loaded, ask parent class loader to load the class.
If parent class loader cannot load class, attempt to load it in this class loader.
When you implement a class loader that is capable of reloading classes you will need to deviate a bit from this sequence. The classes to reload should not be requested loaded by the parent class loader. More on that later.



Dynamic Class Loading
Loading a class dynamically is easy. All you need to do is to obtain a ClassLoader and call its loadClass() method. Here is an example:


public class MainClass {

  public static void main(String[] args){

    ClassLoader classLoader = MainClass.class.getClassLoader();

    try {
        Class aClass = classLoader.loadClass("com.jenkov.MyClass");
        System.out.println("aClass.getName() = " + aClass.getName());
    } catch (ClassNotFoundException e) {
        e.printStackTrace();
    }

}



Dynamic Class Reloading
Dynamic class reloading is a bit more challenging. Java's builtin Class loaders always checks if a class is already loaded before loading it. Reloading the class is therefore not possible using Java's builtin class loaders. To reload a class you will have to implement your own ClassLoader subclass.

Even with a custom subclass of ClassLoader you have a challenge. Every loaded class needs to be linked. This is done using the ClassLoader.resolve() method. This method is final, and thus cannot be overridden in your ClassLoader subclass. The resolve() method will not allow any given ClassLoader instance to link the same class twice. Therefore, everytime you want to reload a class you must use a new instance of your ClassLoader subclass. This is not impossible, but necessary to know when designing for class reloading.



Designing your Code for Class Reloading
As stated earlier you cannot reload a class using a ClassLoader that has already loaded that class once. Therefore you will have to reload the class using a different ClassLoader instance. But this poses som new challenges.

Every class loaded in a Java application is identified by its fully qualified name (package name + class name), and the ClassLoader instance that loaded it. That means, that a class MyObject loaded by class loader A, is not the same class as the MyObject class loaded with class loader B. Look at this code:

MyObject object = (MyObject)
    myClassReloadingFactory.newInstance("com.jenkov.MyObject");

Notice how the MyObject class is referenced in the code, as the type of the object variable. This causes the MyObject class to be loaded by the same class loader that loaded the class this code is residing in.

If the myClassReloadingFactory object factory reloads the MyObject class using a different class loader than the class the above code resides in, you cannot cast the instance of the reloaded MyObject class to the MyObject type of the object variable. Since the two MyObject classes were loaded with different class loaders, the are regarded as different classes, even if they have the same fully qualified class name. Trying to cast an object of the one class to a reference of the other will result in a ClassCastException.

It is possible to work around this limitation but you will have to change your code in either of two ways:

Use an interface as the variable type, and just reload the implementing class.
Use a superclass as the variable type, and just reload a subclass.
Here are two coresponding code examples:

MyObjectInterface object = (MyObjectInterface)
    myClassReloadingFactory.newInstance("com.jenkov.MyObject");

MyObjectSuperclass object = (MyObjectSuperclass)
    myClassReloadingFactory.newInstance("com.jenkov.MyObject");

Either of these two methods will work if the type of the variable, the interface or superclass, is not reloaded when the implementing class or subclass is reloaded.

To make this work you will of course need to implement your class loader to let the interface or superclass be loaded by its parent. When your class loader is asked to load the MyObject class, it will also be asked to load the MyObjectInterface class, or the MyObjectSuperclass class, since these are referenced from within the MyObject class. Your class loader must delegate the loading of those classes to the same class loader that loaded the class containing the interface or superclass typed variables.



ClassLoader Load / Reload Example
The text above has contained a lot of talk. Let's look at a simple example. Below is an example of a simple ClassLoader subclass. Notice how it delegates class loading to its parent except for the one class it is intended to be able to reload. If the loading of this class is delegated to the parent class loader, it cannot be reloaded later. Remember, a class can only be loaded once by the same ClassLoader instance.

As said earlier, this is just an example that serves to show you the basics of a ClassLoader's behaviour. It is not a production ready template for your own class loaders. Your own class loaders should probably not be limited to a single class, but a collection of classes that you know you will need to reload. In addition, you should probably not hardcode the class paths either.

public class MyClassLoader extends ClassLoader{

    public MyClassLoader(ClassLoader parent) {
        super(parent);
    }

    public Class loadClass(String name) throws ClassNotFoundException {
        if(!"reflection.MyObject".equals(name))
                return super.loadClass(name);

        try {
            String url = "file:C:/data/projects/tutorials/web/WEB-INF/" +
                            "classes/reflection/MyObject.class";
            URL myUrl = new URL(url);
            URLConnection connection = myUrl.openConnection();
            InputStream input = connection.getInputStream();
            ByteArrayOutputStream buffer = new ByteArrayOutputStream();
            int data = input.read();

            while(data != -1){
                buffer.write(data);
                data = input.read();
            }

            input.close();

            byte[] classData = buffer.toByteArray();

            return defineClass("reflection.MyObject",
                    classData, 0, classData.length);

        } catch (MalformedURLException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }

        return null;
    }

}


Below is an example use of the MyClassLoader.

public static void main(String[] args) throws
    ClassNotFoundException,
    IllegalAccessException,
    InstantiationException {

    ClassLoader parentClassLoader = MyClassLoader.class.getClassLoader();
    MyClassLoader classLoader = new MyClassLoader(parentClassLoader);
    Class myObjectClass = classLoader.loadClass("reflection.MyObject");

    AnInterface2       object1 =
            (AnInterface2) myObjectClass.newInstance();

    MyObjectSuperClass object2 =
            (MyObjectSuperClass) myObjectClass.newInstance();

    //create new class loader so classes can be reloaded.
    classLoader = new MyClassLoader(parentClassLoader);
    myObjectClass = classLoader.loadClass("reflection.MyObject");

    object1 = (AnInterface2)       myObjectClass.newInstance();
    object2 = (MyObjectSuperClass) myObjectClass.newInstance();
   
}


Here is the reflection.MyObject class that is loaded using the class loader. Notice how it both extends a superclass and implements an interface. This is just for the sake of the example. In your own code you would only have to one of the two - extend or implement.

public class MyObject extends MyObjectSuperClass implements AnInterface2{
    //... body of class ... override superclass methods
    //    or implement interface methods
}



End



































Download the JDK
Search the Tutorials
Home Page « Previous • Trail • Next »
Trail: The Reflection API
Uses of Reflection
Reflection is commonly used by programs which require the ability to examine or modify the runtime behavior of applications running in the Java virtual machine. This is a relatively advanced feature and should be used only by developers who have a strong grasp of the fundamentals of the language. With that caveat in mind, reflection is a powerful technique and can enable applications to perform operations which would otherwise be impossible.

Extensibility Features
An application may make use of external, user-defined classes by creating instances of extensibility objects using their fully-qualified names.
Class Browsers and Visual Development Environments
A class browser needs to be able to enumerate the members of classes. Visual development environments can benefit from making use of type information available in reflection to aid the developer in writing correct code.
Debuggers and Test Tools
Debuggers need to be able to examine private members on classes. Test harnesses can make use of reflection to systematically call a discoverable set APIs defined on a class, to insure a high level of code coverage in a test suite.
Drawbacks of Reflection
Reflection is powerful, but should not be used indiscriminately. If it is possible to perform an operation without using reflection, then it is preferable to avoid using it. The following concerns should be kept in mind when accessing code via reflection.
Performance Overhead
Because reflection involves types that are dynamically resolved, certain Java virtual machine optimizations can not be performed. Consequently, reflective operations have slower performance than their non-reflective counterparts, and should be avoided in sections of code which are called frequently in performance-sensitive applications.
Security Restrictions
Reflection requires a runtime permission which may not be present when running under a security manager. This is in an important consideration for code which has to run in a restricted security context, such as in an Applet.
Exposure of Internals
Since reflection allows code to perform operations that would be illegal in non-reflective code, such as accessing private fields and methods, the use of reflection can result in unexpected side-effects, which may render code dysfunctional and may destroy portability. Reflective code breaks abstractions and therefore may change behavior with upgrades of the platform.
Trail Lessons
This trail covers common uses of reflection for accessing and manipulating classes, fields, methods, and constructors. Each lesson contains code examples, tips, and troubleshooting information.
 Classes
This lesson shows the various ways to obtain a Class object and use it to examine properties of a class, including its declaration and contents.
 Members
This lesson describes how to use the Reflection APIs to find the fields, methods, and constructors of a class. Examples are provided for setting and getting field values, invoking methods, and creating new instances of objects using specific constructors.
 Arrays and Enumerated Types
This lesson introduces two special types of classes: arrays, which are generated at runtime, and enum types, which define unique named object instances. Sample code shows how to retrieve the component type for an array and how to set and get fields with array or enum types.

--------------------------------------------------------------------------------
Note: The examples in this trail are designed for experimenting with the Reflection APIs. The handling of exceptions therefore is not the same as would be used in production code. In particular, in production code it is not recommended to dump stack traces that are visible to the user.
--------------------------------------------------------------------------------

« Previous • TOC • Next »

--------------------------------------------------------------------------------

Problems with the examples? Try Compiling and Running the Examples: FAQs.
Complaints? Compliments? Suggestions? Give us your feedback.
Your use of this page and all the material on pages under "The Java Tutorials" banner, and all the material on pages under "The Java Tutorials" banner is subject to the Terms of Use. Additionally, any example code contained in any of these Java Tutorials pages is also licensed under the Code Sample License.  
 About Oracle | Oracle Technology Network | Terms of Service    Copyright © 1995, 2010 Oracle and/or its affiliates. All rights reserved. 


Previous page: Beginning of Tutorial
Next page: Classes





Skip to Content Sun
Sun.com
About Sun
Downloads
Products
Solutions
Support
Training

 Java
Java for your computer
Stay up to date with the latest versions of Java for your desktop computer.

Free and Open Source Java
Get your own copy of the underlying software code for the Java language.

Download the latest JDK
The basic developer kit for Java developers.

Download the Java EE SDK
The SDK supports Java SE 6 and the latest Java EE 5 technologies.

Download NetBeans IDE
Get the award-winning, open-source tool suite for developing Java applications.

Java Developer Resources
Visit java.sun.com for everything you need to know about the Java technology.
Java Developer Tools
See and download all software tools available from Sun.

Java Standard Edition
For developing and deploying Java applications for the desktop, servers, embedded, and real-time environments.

Java Enterprise Edition
For enterprise, server-side Java applications.

Java Micro Edition
For Java applications running on mobile devices.

Java Training
Sharpen your Java skills with courses from the source.

Java Support
Get dedicated help from Sun including technical assistance, product support, and support for deployed Java applications.

 Solaris
OpenSolaris
Download, develop and collaborate with OpenSolaris

Solaris
Download the most advanced operating system in the world

Sun Studio
Optimizing compilers and tools for C/C++/Fortran application development

Solaris Developer Center
Explore the resources and community available to the Solaris developer.

Sun Developer Services
Get technical assistance, product support, training, and other services from the source.

BigAdmin
A community site with Solaris system administration information, hardware compatibility, a script library, and other resources for administrators of Sun products.
 Communities My SDN Account
Update My Profile

  » search tips      APIs Downloads Products Support Training Participate SDN Home > Products & Technologies > Java Technology > Reference > Technical Articles and Tips > Developer Technical Articles & Tips > Advanced Language Topics >  



Article
Using Java Reflection
     
     Print-friendly Version


   



Articles Index


By Glen McCluskey
January 1998

Reflection is a feature in the Java programming language. It allows an executing Java program to examine or "introspect" upon itself, and manipulate internal properties of the program. For example, it's possible for a Java class to obtain the names of all its members and display them.

The ability to examine and manipulate a Java class from within itself may not sound like very much, but in other programming languages this feature simply doesn't exist. For example, there is no way in a Pascal, C, or C++ program to obtain information about the functions defined within that program.

One tangible use of reflection is in JavaBeans, where software components can be manipulated visually via a builder tool. The tool uses reflection to obtain the properties of Java components (classes) as they are dynamically loaded.

A Simple Example
To see how reflection works, consider this simple example:

   import java.lang.reflect.*;

   public class DumpMethods {
      public static void main(String args[])
      {
         try {
            Class c = Class.forName(args[0]);
            Method m[] = c.getDeclaredMethods();
            for (int i = 0; i < m.length; i++)
            System.out.println(m[i].toString());
         }
         catch (Throwable e) {
            System.err.println(e);
         }
      }
   }



For an invocation of:

  java DumpMethods java.util.Stack
the output is:

  public java.lang.Object java.util.Stack.push(
    java.lang.Object)
   public synchronized
     java.lang.Object java.util.Stack.pop()
   public synchronized
      java.lang.Object java.util.Stack.peek()
   public boolean java.util.Stack.empty()
   public synchronized
     int java.util.Stack.search(java.lang.Object)



That is, the method names of class java.util.Stack are listed, along with their fully qualified parameter and return types.

This program loads the specified class using class.forName, and then calls getDeclaredMethods to retrieve the list of methods defined in the class. java.lang.reflect.Method is a class representing a single class method.

Setting Up to Use Reflection
The reflection classes, such as Method, are found in java.lang.reflect. There are three steps that must be followed to use these classes. The first step is to obtain a java.lang.Class object for the class that you want to manipulate. java.lang.Class is used to represent classes and interfaces in a running Java program.

One way of obtaining a Class object is to say:

   Class c = Class.forName("java.lang.String");
to get the Class object for String. Another approach is to use:
   Class c = int.class;
or
  Class c = Integer.TYPE;
to obtain Class information on fundamental types. The latter approach accesses the predefined TYPE field of the wrapper (such as Integer) for the fundamental type.
The second step is to call a method such as getDeclaredMethods, to get a list of all the methods declared by the class.

Once this information is in hand, then the third step is to use the reflection API to manipulate the information. For example, the sequence:

   Class c = Class.forName("java.lang.String");
   Method m[] = c.getDeclaredMethods();
   System.out.println(m[0].toString());
will display a textual representation of the first method declared in String.
In the examples below, the three steps are combined to present self contained illustrations of how to tackle specific applications using reflection.

Simulating the instanceof Operator
Once Class information is in hand, often the next step is to ask basic questions about the Class object. For example, the Class.isInstance method can be used to simulate the instanceof operator:

   class A {}

   public class instance1 {
      public static void main(String args[])
      {
         try {
            Class cls = Class.forName("A");
            boolean b1
              = cls.isInstance(new Integer(37));
            System.out.println(b1);
            boolean b2 = cls.isInstance(new A());
            System.out.println(b2);
         }
         catch (Throwable e) {
            System.err.println(e);
         }
      }
   }


In this example, a Class object for A is created, and then class instance objects are checked to see whether they are instances of A. Integer(37) is not, but new A() is.
Finding Out About Methods of a Class
One of the most valuable and basic uses of reflection is to find out what methods are defined within a class. To do this the following code can be used:


   import java.lang.reflect.*;

   public class method1 {
      private int f1(
       Object p, int x) throws NullPointerException
      {
         if (p == null)
            throw new NullPointerException();
         return x;
      }
       
      public static void main(String args[])
      {
         try {
           Class cls = Class.forName("method1");
       
            Method methlist[]
              = cls.getDeclaredMethods();
            for (int i = 0; i < methlist.length;
               i++) { 
               Method m = methlist[i];
               System.out.println("name
                 = " + m.getName());
               System.out.println("decl class = " +
                              m.getDeclaringClass());
               Class pvec[] = m.getParameterTypes();
               for (int j = 0; j < pvec.length; j++)
                  System.out.println("
                   param #" + j + " " + pvec[j]);
               Class evec[] = m.getExceptionTypes();
               for (int j = 0; j < evec.length; j++)
                  System.out.println("exc #" + j
                    + " " + evec[j]);
               System.out.println("return type = " +
                                  m.getReturnType());
               System.out.println("-----");
            }
         }
         catch (Throwable e) {
            System.err.println(e);
         }
      }
   }


The program first gets the Class description for method1, and then calls getDeclaredMethods to retrieve a list of Method objects, one for each method defined in the class. These include public, protected, package, and private methods. If you use getMethods in the program instead of getDeclaredMethods, you can also obtain information for inherited methods.
Once a list of the Method objects has been obtained, it's simply a matter of displaying the information on parameter types, exception types, and the return type for each method. Each of these types, whether they are fundamental or class types, is in turn represented by a Class descriptor.

The output of the program is:   name = f1
   decl class = class method1
   param #0 class java.lang.Object
   param #1 int
   exc #0 class java.lang.NullPointerException
   return type = int
   -----
   name = main
   decl class = class method1
   param #0 class [Ljava.lang.String;
   return type = void
   -----



Obtaining Information About Constructors
A similar approach is used to find out about the constructors of a class. For example:

 import java.lang.reflect.*;
       
   public class constructor1 {
      public constructor1()
      {
      }
       
      protected constructor1(int i, double d)
      {
      }
        
      public static void main(String args[])
      {
         try {
           Class cls = Class.forName("constructor1");
       
           Constructor ctorlist[]
               = cls.getDeclaredConstructors();
         for (int i = 0; i < ctorlist.length; i++) {
               Constructor ct = ctorlist[i];
               System.out.println("name
                 = " + ct.getName());
               System.out.println("decl class = " +
                            ct.getDeclaringClass());
               Class pvec[] = ct.getParameterTypes();
               for (int j = 0; j < pvec.length; j++)
                  System.out.println("param #"
                     + j + " " + pvec[j]);
               Class evec[] = ct.getExceptionTypes();
               for (int j = 0; j < evec.length; j++)
                  System.out.println(
                    "exc #" + j + " " + evec[j]);
               System.out.println("-----");
            }
          }
          catch (Throwable e) {
             System.err.println(e);
          }
      }
   }


There is no return-type information retrieved in this example, because constructors don't really have a true return type.
When this program is run, the output is:

   name = constructor1
   decl class = class constructor1
   -----
   name = constructor1
   decl class = class constructor1
   param #0 int
   param #1 double
   -----



Finding Out About Class Fields
It's also possible to find out which data fields are defined in a class. To do this, the following code can be used:


   import java.lang.reflect.*;
       
   public class field1 {
      private double d;
      public static final int i = 37;
      String s = "testing";
       
      public static void main(String args[])
      {
         try {
            Class cls = Class.forName("field1");
       
            Field fieldlist[]
              = cls.getDeclaredFields();
            for (int i
              = 0; i < fieldlist.length; i++) {
               Field fld = fieldlist[i];
               System.out.println("name
                  = " + fld.getName());
               System.out.println("decl class = " +
                           fld.getDeclaringClass());
               System.out.println("type
                  = " + fld.getType());
               int mod = fld.getModifiers();
               System.out.println("modifiers = " +
                          Modifier.toString(mod));
               System.out.println("-----");
            }
          }
          catch (Throwable e) {
             System.err.println(e);
          }
       }
   }


This example is similar to the previous ones. One new feature is the use of Modifier. This is a reflection class that represents the modifiers found on a field member, for example "private int". The modifiers themselves are represented by an integer, and Modifier.toString is used to return a string representation in the "official" declaration order (such as "static" before "final"). The output of the program is:   name = d
   decl class = class field1
   type = double
   modifiers = private
   -----
   name = i
   decl class = class field1
   type = int
   modifiers = public static final
   -----
   name = s
   decl class = class field1
   type = class java.lang.String
   modifiers =
   -----


As with methods, it's possible to obtain information about just the fields declared in a class (getDeclaredFields), or to also get information about fields defined in superclasses (getFields).
Invoking Methods by Name
So far the examples that have been presented all relate to obtaining class information. But it's also possible to use reflection in other ways, for example to invoke a method of a specified name.

To see how this works, consider the following example:

   import java.lang.reflect.*;
       
   public class method2 {
      public int add(int a, int b)
      {
         return a + b;
      }
       
      public static void main(String args[])
      {
         try {
           Class cls = Class.forName("method2");
           Class partypes[] = new Class[2];
            partypes[0] = Integer.TYPE;
            partypes[1] = Integer.TYPE;
            Method meth = cls.getMethod(
              "add", partypes);
            method2 methobj = new method2();
            Object arglist[] = new Object[2];
            arglist[0] = new Integer(37);
            arglist[1] = new Integer(47);
            Object retobj
              = meth.invoke(methobj, arglist);
            Integer retval = (Integer)retobj;
            System.out.println(retval.intValue());
         }
         catch (Throwable e) {
            System.err.println(e);
         }
      }
   }


Suppose that a program wants to invoke the add method, but doesn't know this until execution time. That is, the name of the method is specified during execution (this might be done by a JavaBeans development environment, for example). The above program shows a way of doing this.
getMethod is used to find a method in the class that has two integer parameter types and that has the appropriate name. Once this method has been found and captured into a Method object, it is invoked upon an object instance of the appropriate type. To invoke a method, a parameter list must be constructed, with the fundamental integer values 37 and 47 wrapped in Integer objects. The return value (84) is also wrapped in an Integer object.

Creating New Objects
There is no equivalent to method invocation for constructors, because invoking a constructor is equivalent to creating a new object (to be the most precise, creating a new object involves both memory allocation and object construction). So the nearest equivalent to the previous example is to say:

   import java.lang.reflect.*;
       
   public class constructor2 {
      public constructor2()
      {
      }
       
      public constructor2(int a, int b)
      {
         System.out.println(
           "a = " + a + " b = " + b);
      }
       
      public static void main(String args[])
      {
         try {
           Class cls = Class.forName("constructor2");
           Class partypes[] = new Class[2];
            partypes[0] = Integer.TYPE;
            partypes[1] = Integer.TYPE;
            Constructor ct
              = cls.getConstructor(partypes);
            Object arglist[] = new Object[2];
            arglist[0] = new Integer(37);
            arglist[1] = new Integer(47);
            Object retobj = ct.newInstance(arglist);
         }
         catch (Throwable e) {
            System.err.println(e);
         }
      }
   }


which finds a constructor that handles the specified parameter types and invokes it, to create a new instance of the object. The value of this approach is that it's purely dynamic, with constructor lookup and invocation at execution time, rather than at compilation time.
Changing Values of Fields
Another use of reflection is to change the values of data fields in objects. The value of this is again derived from the dynamic nature of reflection, where a field can be looked up by name in an executing program and then have its value changed. This is illustrated by the following example:

   import java.lang.reflect.*;
       
   public class field2 {
      public double d;
       
      public static void main(String args[])
      {
         try {
            Class cls = Class.forName("field2");
            Field fld = cls.getField("d");
            field2 f2obj = new field2();
            System.out.println("d = " + f2obj.d);
            fld.setDouble(f2obj, 12.34);
            System.out.println("d = " + f2obj.d);
         }
         catch (Throwable e) {
            System.err.println(e);
         }
      }
   }


In this example, the d field has its value set to 12.34.
Using Arrays
One final use of reflection is in creating and manipulating arrays. Arrays in the Java language are a specialized type of class, and an array reference can be assigned to an Object reference.

To see how arrays work, consider the following example:

   import java.lang.reflect.*;
       
   public class array1 {
      public static void main(String args[])
      {
         try {
            Class cls = Class.forName(
              "java.lang.String");
            Object arr = Array.newInstance(cls, 10);
            Array.set(arr, 5, "this is a test");
            String s = (String)Array.get(arr, 5);
            System.out.println(s);
         }
         catch (Throwable e) {
            System.err.println(e);
         }
      }
   }


This example creates a 10-long array of Strings, and then sets location 5 in the array to a string value. The value is retrieved and displayed.
A more complex manipulation of arrays is illustrated by the following code:

   import java.lang.reflect.*;
       
   public class array2 {
      public static void main(String args[])
      {
         int dims[] = new int[]{5, 10, 15};
         Object arr
           = Array.newInstance(Integer.TYPE, dims);
       
         Object arrobj = Array.get(arr, 3);
         Class cls =
           arrobj.getClass().getComponentType();
         System.out.println(cls);
         arrobj = Array.get(arrobj, 5);
         Array.setInt(arrobj, 10, 37);
       
         int arrcast[][][] = (int[][][])arr;
         System.out.println(arrcast[3][5][10]);
      }
   }


This example creates a 5 x 10 x 15 array of ints, and then proceeds to set location [3][5][10] in the array to the value 37. Note here that a multi-dimensional array is actually an array of arrays, so that, for example, after the first Array.get, the result in arrobj is a 10 x 15 array. This is peeled back once again to obtain a 15-long array, and the 10th slot in that array is set using Array.setInt.
Note that the type of array that is created is dynamic, and does not have to be known at compile time.

Summary
Java reflection is useful because it supports dynamic retrieval of information about classes and data structures by name, and allows for their manipulation within an executing Java program. This feature is extremely powerful and has no equivalent in other conventional languages such as C, C++, Fortran, or Pascal. 

Glen McCluskey has focused on programming languages since 1988. He consults in the areas of Java and C++ performance, testing, and technical documentation.





 
 

Oracle is reviewing the Sun product roadmap and will provide guidance to customers in accordance with Oracle's standard product communication policies. Any resulting features and timing of release of such features as determined by Oracle's review of roadmaps, are at the sole discretion of Oracle. All product roadmap information, whether communicated by Sun Microsystems or by Oracle, does not represent a commitment to deliver any material, code, or functionality, and should not be relied upon in making purchasing decisions. It is intended for information purposes only, and may not be incorporated into any contract.


Lesson: Classes
Every object is either a reference or primitive type. Reference types all inherit from java.lang.Object. Classes, enums, arrays, and interfaces are all reference types. There is a fixed set of primitive types: boolean, byte, short, int, long, char, float, and double. Examples of reference types include java.lang.String, all of the wrapper classes for primitive types such as java.lang.Double, the interface java.io.Serializable, and the enum javax.swing.SortOrder.
For every type of object, the Java virtual machine instantiates an immutable instance of java.lang.Class which provides methods to examine the runtime properties of the object including its members and type information. Class also provides the ability to create new classes and objects. Most importantly, it is the entry point for all of the Reflection APIs. This lesson covers the most commonly used reflection operations involving classes:

Retrieving Class Objects describes the ways to get a Class
Examining Class Modifiers and Types shows how to access the class declaration information
Discovering Class Members illustrates how to list the constructors, fields, methods, and nested classes in a class
Troubleshooting describes common errors encountered when using Class

Retrieving Class Objects
The entry point for all reflection operations is java.lang.Class. With the exception of java.lang.reflect.ReflectPermission, none of the classes in java.lang.reflect have public constructors. To get to these classes, it is necessary to invoke appropriate methods on Class. There are several ways to get a Class depending on whether the code has access to an object, the name of class, a type, or an existing Class.
Object.getClass()
If an instance of an object is available, then the simplest way to get its Class is to invoke Object.getClass(). Of course, this only works for reference types which all inherit from Object. Some examples follow.
Class c = "foo".getClass();

Returns the Class for String
Class c = System.console().getClass();

There is a unique console associated with the virtual machine which is returned by the static method System.console(). The value returned by getClass() is the Class corresponding to java.io.Console.
enum E { A, B }
Class c = A.getClass();

A is is an instance of the enum E; thus getClass() returns the Class corresponding to the enumeration type E.
byte[] bytes = new byte[1024];
Class c = bytes.getClass();

Since arrays are Objects, it is also possible to invoke getClass() on an instance of an array. The returned Class corresponds to an array with component type byte.
import java.util.HashSet;
import java.util.Set;

Set<String> s = new HashSet<String>();
Class c = s.getClass();

In this case, java.util.Set is an interface to an object of type java.util.HashSet. The value returned by getClass() is the class corresponding to java.util.HashSet.
The .class Syntax
If the type is available but there is no instance then it is possible to obtain a Class by appending ".class" to the name of the type. This is also the easiest way to obtain the Class for a primitive type.
boolean b;
Class c = b.getClass();   // compile-time error

Class c = boolean.class;  // correct

Note that the statement boolean.getClass() would produce a compile-time error because a boolean is a primitive type and cannot be dereferenced. The .class syntax returns the Class corresponding to the type boolean.
Class c = java.io.PrintStream.class;

The variable c will be the Class corresponding to the type java.io.PrintStream.
Class c = int[][][].class;

The .class syntax may be used to retrieve a Class corresponding to a multi-dimensional array of a given type.
Class.forName()
If the fully-qualified name of a class is available, it is possible to get the corresponding Class using the static method Class.forName(). This cannot be used for primitive types. The syntax for names of array classes is described by Class.getName(). This syntax is applicable to references and primitive types.
Class c = Class.forName("com.duke.MyLocaleServiceProvider");

This statement will create a class from the given fully-qualified name.
Class cDoubleArray = Class.forName("[D");

Class cStringArray = Class.forName("[[Ljava.lang.String;");

The variable cDoubleArray will contain the Class corresponding to an array of primitive type double (i.e. the same as double[].class). The cStringArray variable will contain the Class corresponding to a two-dimensional array of String (i.e. identical to String[][].class).
TYPE Field for Primitive Type Wrappers
The .class syntax is a more convenient and the preferred way to obtain the Class for a primitive type; however there is another way to acquire the Class. Each of the primitive types and void has a wrapper class in java.lang that is used for boxing of primitive types to reference types. Each wrapper class contains a field named TYPE which is equal to the Class for the primitive type being wrapped.
Class c = Double.TYPE;

There is a class java.lang.Double which is used to wrap the primitive type double whenever an Object is required. The value of Double.TYPE is identical to that of double.class.
Class c = Void.TYPE;

Void.TYPE is identical to void.class.
Methods that Return Classes
There are several Reflection APIs which return classes but these may only be accessed if a Class has already been obtained either directly or indirectly.
Class.getSuperclass()
Returns the super class for the given class.
Class c = javax.swing.JButton.class.getSuperclass();

The super class of javax.swing.JButton is javax.swing.AbstractButton.
Class.getClasses()
Returns all the public classes, interfaces, and enums that are members of the class including inherited members.
Class<?>[] c = Character.class.getClasses();

Character contains two member classes Character.Subset and Character.UnicodeBlock.
Class.getDeclaredClasses()
Returns all of the classes interfaces, and enums that are explicitly declared in this class.
Class<?>[] c = Character.class.getDeclaredClasses();

Character contains two public member classes Character.Subset and Character.UnicodeBlock and one private class Character.CharacterCache.
{ Class, java.lang.reflect. { Field, Method, Constructor } }.getDeclaringClass()
Returns the Class in which these members were declared. Anonymous classes will not have a declaring class but will have an enclosing class.
import java.lang.reflect.Field;

Field f = System.class.getField("out");
Class c = f.getDeclaringClass();

The field out is declared in System.
public class MyClass {
    static Object o = new Object() { public void m() {} };
    static Class<c> = o.getClass().getEnclosingClass();
}

The declaring class of the anonymous class defined by o is null.
Class.getEnclosingClass()
Returns the immediately enclosing class of the class.
Class c = Thread.State.class().getEnclosingClass();

The enclosing class of the enum Thread.State is Thread.
public class MyClass {
    static Object o = new Object() { public void m() {} };
    static Class<c> = o.getClass().getEnclosingClass();
}

The anonymous class defined by o is enclosed by MyClass.









Examining Class Modifiers and Types
A class may be declared with one or more modifiers which affect its runtime behavior:
  • Access modifiers: public, protected, and private
  • Modifier requiring override: abstract
  • Modifier restricting to one instance: static
  • Modifier prohibiting value modification: final
  • Modifier forcing strict floating point behavior: strictfp
  • Annotations
Not all modifiers are allowed on all classes, for example an interface cannot be final and an enum cannot be abstract. java.lang.reflect.Modifier contains declarations for all possible modifiers. It also contains methods which may be used to decode the set of modifiers returned by Class.getModifiers().
The ClassDeclarationSpy example shows how to obtain the declaration components of a class including the modifiers, generic type parameters, implemented interfaces, and the inheritance path. Since Class implements the java.lang.reflect.AnnotatedElement interface it is also possible to query the runtime annotations.
 
import java.lang.annotation.Annotation;
import java.lang.reflect.Modifier;
import java.lang.reflect.Type;
import java.lang.reflect.TypeVariable;
import java.util.Arrays;
import java.util.ArrayList;
import java.util.List;
import static java.lang.System.out;
 
public class ClassDeclarationSpy {
    public static void main(String... args) {
        try {
            Class<?> c = Class.forName(args[0]);
            out.format("Class:%n  %s%n%n", c.getCanonicalName());
            out.format("Modifiers:%n  %s%n%n",
                      Modifier.toString(c.getModifiers()));
 
            out.format("Type Parameters:%n");
            TypeVariable[] tv = c.getTypeParameters();
            if (tv.length != 0) {
               out.format("  ");
               for (TypeVariable t : tv)
                   out.format("%s ", t.getName());
               out.format("%n%n");
            } else {
               out.format("  -- No Type Parameters --%n%n");
            }
 
            out.format("Implemented Interfaces:%n");
            Type[] intfs = c.getGenericInterfaces();
            if (intfs.length != 0) {
               for (Type intf : intfs)
                   out.format("  %s%n", intf.toString());
               out.format("%n");
            } else {
               out.format("  -- No Implemented Interfaces --%n%n");
            }
 
            out.format("Inheritance Path:%n");
            List<Class> l = new ArrayList<Class>();
            printAncestor(c, l);
            if (l.size() != 0) {
               for (Class<?> cl : l)
                   out.format("  %s%n", cl.getCanonicalName());
               out.format("%n");
            } else {
               out.format("  -- No Super Classes --%n%n");
            }
 
            out.format("Annotations:%n");
            Annotation[] ann = c.getAnnotations();
            if (ann.length != 0) {
               for (Annotation a : ann)
                   out.format("  %s%n", a.toString());
               out.format("%n");
            } else {
               out.format("  -- No Annotations --%n%n");
            }
 
        // production code should handle this exception more gracefully
        } catch (ClassNotFoundException x) {
            x.printStackTrace();
        }
    }
 
    private static void printAncestor(Class<?> c, List<Class> l) {
        Class<?> ancestor = c.getSuperclass();
       if (ancestor != null) {
            l.add(ancestor);
            printAncestor(ancestor, l);
       }
    }
}
A few samples of the output follows. User input is in italics.
$ java ClassDeclarationSpy java.util.concurrent.ConcurrentNavigableMap
Class:
  java.util.concurrent.ConcurrentNavigableMap
 
Modifiers:
  public abstract interface
 
Type Parameters:
  K V
 
Implemented Interfaces:
  java.util.concurrent.ConcurrentMap<K, V>
  java.util.NavigableMap<K, V>
 
Inheritance Path:
  -- No Super Classes --
 
Annotations:
  -- No Annotations --
This is the actual declaration for java.util.concurrent.ConcurrentNavigableMap in the source code:
public interface ConcurrentNavigableMap<K,V>
    extends ConcurrentMap, NavigableMap<K,V>
Note that since this is an interface, it is implicitly abstract. The compiler adds this modifier for every interface. Also, this declaration contains two generic type parameters, K and V. The example code simply prints the names of these parameters, but is it possible to retrieve additional information about them using methods in java.lang.reflect.TypeVariable. Interfaces may also implement other interfaces as shown above.
$ java ClassDeclarationSpy "[Ljava.lang.String;"
Class:
  java.lang.String[]
 
Modifiers:
  public abstract final
 
Type Parameters:
  -- No Type Parameters --
 
Implemented Interfaces:
  interface java.lang.Cloneable
  interface java.io.Serializable
 
Inheritance Path:
  java.lang.Object
 
Annotations:
  -- No Annotations --
Since arrays are runtime objects, all of the type information is defined by the Java virtual machine. In particular, arrays implement Cloneable and java.io.Serializable and their direct superclass is always Object.
$ java ClassDeclarationSpy java.io.InterruptedIOException
Class:
  java.io.InterruptedIOException
 
Modifiers:
  public
 
Type Parameters:
  -- No Type Parameters --
 
Implemented Interfaces:
  -- No Implemented Interfaces --
 
Inheritance Path:
  java.io.IOException
  java.lang.Exception
  java.lang.Throwable
  java.lang.Object
 
Annotations:
  -- No Annotations --
From the inheritance path, it may be deduced that java.io.InterruptedIOException is a checked exception because RuntimeException is not present.
$ java ClassDeclarationSpy java.security.Identity
Class:
  java.security.Identity
 
Modifiers:
  public abstract
 
Type Parameters:
  -- No Type Parameters --
 
Implemented Interfaces:
  interface java.security.Principal
  interface java.io.Serializable
 
Inheritance Path:
  java.lang.Object
 
Annotations:
  @java.lang.Deprecated()
This output shows that java.security.Identity, a deprecated API, possesses the annotation java.lang.Deprecated. This may be used by reflective code to detect deprecated APIs.


Discovering Class Members
There are two categories of methods provided in Class for accessing fields, methods, and constructors: methods which enumerate these members and methods which search for particular members. Also there are distinct methods for accessing members declared directly on the class versus methods which search the superinterfaces and superclasses for inherited members. The following table provides a summary of all the member-locating methods and their characteristics.
Class Methods for Locating Members Member  Class API  List of members?  Inherited members?  Private members? 
Field  getDeclaredField() no no yes 
getField() no yes no 
getDeclaredFields() yes no yes 
getFields() yes yes no 
Method  getDeclaredMethod() no no yes 
getMethod() no yes no 
getDeclaredMethods() yes no yes 
getMethods() yes yes no 
Constructor  getDeclaredConstructor() no N/A1 yes 
getConstructor() no N/A1 no 
getDeclaredConstructors() yes N/A1 yes 
getConstructors() yes N/A1 no 


1 Constructors are not inherited.

Given a class name and an indication of which members are of interest, the ClassSpy example uses the get*s() methods to determine the list of all public elements, including any which are inherited.


import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.lang.reflect.Member;
import static java.lang.System.out;

enum ClassMember { CONSTRUCTOR, FIELD, METHOD, CLASS, ALL }

public class ClassSpy {
    public static void main(String... args) {
            try {
                Class<?> c = Class.forName(args[0]);
                out.format("Class:%n  %s%n%n", c.getCanonicalName());

                Package p = c.getPackage();
                out.format("Package:%n  %s%n%n",
                               (p != null ? p.getName() : "-- No Package --"));

                for (int i = 1; i < args.length; i++) {
                        switch (ClassMember.valueOf(args[i])) {
                        case CONSTRUCTOR:
                            printMembers(c.getConstructors(), "Constructor");
                            break;
                        case FIELD:
                            printMembers(c.getFields(), "Fields");
                            break;
                        case METHOD:
                            printMembers(c.getMethods(), "Methods");
                            break;
                        case CLASS:
                            printClasses(c);
                            break;
                        case ALL:
                            printMembers(c.getConstructors(), "Constuctors");
                            printMembers(c.getFields(), "Fields");
                            printMembers(c.getMethods(), "Methods");
                            printClasses(c);
                            break;
                        default:
                            assert false;
                        }
                }

        // production code should handle these exceptions more gracefully
            } catch (ClassNotFoundException x) {
                x.printStackTrace();
            }
    }

    private static void printMembers(Member[] mbrs, String s) {
            out.format("%s:%n", s);
            for (Member mbr : mbrs) {
                if (mbr instanceof Field)
                        out.format("  %s%n", ((Field)mbr).toGenericString());
                else if (mbr instanceof Constructor)
                        out.format("  %s%n", ((Constructor)mbr).toGenericString());
                else if (mbr instanceof Method)
                        out.format("  %s%n", ((Method)mbr).toGenericString());
            }
            if (mbrs.length == 0)
                out.format("  -- No %s --%n", s);
            out.format("%n");
    }

    private static void printClasses(Class<?> c) {
            out.format("Classes:%n");
            Class<?>[] clss = c.getClasses();
            for (Class<?> cls : clss)
                out.format("  %s%n", cls.getCanonicalName());
            if (clss.length == 0)
                out.format("  -- No member interfaces, classes, or enums --%n");
            out.format("%n");
    }
}

This example is relatively compact; however the printMembers() method is slightly awkward due to the fact that the java.lang.reflect.Member interface has existed since the earliest implementations of reflection and it could not be modified to include the more useful getGenericString() method when generics were introduced. The only alternatives are to test and cast as shown, replace this method with printConstructors(), printFields(), and printMethods(), or to be satisfied with the relatively spare results of Member.getName().

Samples of the output and their interpretation follows. User input is in italics.

$ java ClassSpy java.lang.ClassCastException CONSTRUCTOR
Class:
  java.lang.ClassCastException

Package:
  java.lang

Constructor:
  public java.lang.ClassCastException()
  public java.lang.ClassCastException(java.lang.String)

Since constructors are not inherited, the exception chaining mechanism constructors (those with a Throwable parameter) which are defined in the immediate super class RuntimeException and other super classes are not found.

$ java ClassSpy java.nio.channels.ReadableByteChannel METHOD
Class:
  java.nio.channels.ReadableByteChannel

Package:
  java.nio.channels

Methods:
  public abstract int java.nio.channels.ReadableByteChannel.read(java.nio.ByteBuffer) throws java.io.IOException
  public abstract void java.nio.channels.Channel.close() throws java.io.IOException
  public abstract boolean java.nio.channels.Channel.isOpen()

The interface java.nio.channels.ReadableByteChannel defines read(). The remaining methods are inherited from a super interface. This code could easily be modified to list only those methods that are actually declared in the class by replacing get*s() with getDeclared*s().
$ java ClassSpy ClassMember FIELD METHOD
Class:
  ClassMember

Package:
  -- No Package --

Fields:
  public static final ClassMember ClassMember.CONSTRUCTOR
  public static final ClassMember ClassMember.FIELD
  public static final ClassMember ClassMember.METHOD
  public static final ClassMember ClassMember.CLASS
  public static final ClassMember ClassMember.ALL

Methods:
  public static ClassMember ClassMember.valueOf(java.lang.String)
  public static ClassMember[] ClassMember.values()
  public final int java.lang.Enum.hashCode()
  public final int java.lang.Enum.compareTo(E)
  public int java.lang.Enum.compareTo(java.lang.Object)
  public final java.lang.String java.lang.Enum.name()
  public final boolean java.lang.Enum.equals(java.lang.Object)
  public java.lang.String java.lang.Enum.toString()
  public static <T> T java.lang.Enum.valueOf(java.lang.Class<T>,java.lang.String)
  public final java.lang.Class<E> java.lang.Enum.getDeclaringClass()
  public final int java.lang.Enum.ordinal()
  public final native java.lang.Class<?> java.lang.Object.getClass()
  public final native void java.lang.Object.wait(long) throws java.lang.InterruptedException
  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.notify()
  public final native void java.lang.Object.notifyAll()

In the fields portion of these results, enum constants are listed. While these are technically fields, it might be useful to distinguish them from other fields. This example could be modified to use java.lang.reflect.Field.isEnumConstant() for this purpose. The EnumSpy example in a later section of this trail, Examining Enums, contains a possible implementation.

In the methods section of the output, observe that the method name includes the name of the declaring class. Thus, the toString() method is implemented by Enum, not inherited from Object. The code could be amended to make this more obvious by using Field.getDeclaringClass(). The following fragment illustrates part of a potential solution.

if (mbr instanceof Field) {
    Field f = (Field)mbr;
    out.format("  %s%n", f.toGenericString());
    out.format("  -- declared in: %s%n", f.getDeclaringClass());
}

Troubleshooting
The following examples show typical errors which may be encountered when reflecting on classes.
Compiler Warning: "Note: ... uses unchecked or unsafe operations"
When a method is invoked, the types of the argument values are checked and possibly converted. ClassWarning invokes getMethod() to cause a typical unchecked conversion warning:


import java.lang.reflect.Method;

public class ClassWarning {
    void m() {
            try {
                Class c = ClassWarning.class;
                Method m = c.getMethod("m");  // warning

        // production code should handle this exception more gracefully
            } catch (NoSuchMethodException x) {
                x.printStackTrace();
            }
    }
}

$ javac ClassWarning.java
Note: ClassWarning.java uses unchecked or unsafe operations.
Note: Recompile with -Xlint:unchecked for details.
$ javac -Xlint:unchecked ClassWarning.java
ClassWarning.java:7: warning: [unchecked] unchecked call to getMethod(java.lang.String,java.lang.Class<?>...) as a member of the raw type java.lang.Class
            Method m = c.getMethod("m");  // warning
                                  ^
1 warning

Many library methods have been retrofitted with generic declarations including several in Class. Since c is declared as a raw type (has no type parameters) and the corresponding parameter of getMethod() is a parameterized type, an unchecked conversion occurs. The compiler is required to generate a warning. (See The Java Language Specification, Third Edition, sections 5.1.9 and 5.3.)
There are two possible solutions. The more preferable it to modify the declaration of c to include an appropriate generic type. In this case, the declaration should be:

Class<?> c = warn.getClass();

Alternatively, the warning could be explicitly suppressed using the predefined annotation @SuppressWarnings preceding the problematic statement.
Class c = ClassWarning.class;
@SuppressWarnings("unchecked")
Method m = c.getMethod("m");  // warning gone


--------------------------------------------------------------------------------
Tip: As a general principle, warnings should not be ignored as they may indicate the presence of a bug. Parameterized declarations should be used as appropriate. If that is not possible (perhaps because an application must interact with a library vendor's code), annotate the offending line using @SuppressWarnings.
--------------------------------------------------------------------------------

InstantiationException when the Constructor is Not Accessible
Class.newInstance() will throw an InstantiationException if an attempt is made to create a new instance of the class and the zero-argument constructor is not visible. The ClassTrouble example illustrates the resulting stack trace.


class Cls {
    private Cls() {}
}

public class ClassTrouble {
    public static void main(String... args) {
            try {
                Class<?> c = Class.forName("Cls");
                c.newInstance();  // InstantiationException

        // production code should handle these exceptions more gracefully
            } catch (InstantiationException x) {
                x.printStackTrace();
            } catch (IllegalAccessException x) {
                x.printStackTrace();
            } catch (ClassNotFoundException x) {
                x.printStackTrace();
            }
    }
}

$ java ClassTrouble
java.lang.IllegalAccessException: Class ClassTrouble can not access a member of
class Cls with modifiers "private"
        at sun.reflect.Reflection.ensureMemberAccess(Reflection.java:65)
        at java.lang.Class.newInstance0(Class.java:349)
        at java.lang.Class.newInstance(Class.java:308)
        at ClassTrouble.main(ClassTrouble.java:9)

Class.newInstance() behaves very much like the new keyword and will fail for the same reasons new would fail. The typical solution in reflection is to take advantage of the java.lang.reflect.AccessibleObject class which provides the ability to suppress access control checks; however, this approach will not work because java.lang.Class does not extend AccessibleObject. The only solution is to modify the code to use Constructor.newInstance() which does extend AccessibleObject.

--------------------------------------------------------------------------------
Tip: In general, it is preferable to use Constructor.newInstance() for the reasons described in the Creating New Class Instances section in the Members lesson.
--------------------------------------------------------------------------------

Additional examples of potential problems using Constructor.newInstance() may be found in the Constructor Troubleshooting section of the Members lesson.
Lesson: Members
Reflection defines an interface java.lang.reflect.Member which is implemented by java.lang.reflect.Field, java.lang.reflect.Method, and java.lang.reflect.Constructor . These objects will be discussed in this lesson. For each member, the lesson will describe the associated APIs to retrieve declaration and type information, any operations unique to the member (for example, setting the value of a field or invoking a method), and commonly encountered errors. Each concept will be illustrated with code samples and related output which approximate some expected reflection uses.

--------------------------------------------------------------------------------
Note: According to The Java Language Specification, Third Edition, the members of a class are the inherited components of the class body including fields, methods, nested classes, interfaces, and enumerated types. Since constructors are not inherited, they are not members. This differs from the implementing classes of java.lang.reflect.Member.
--------------------------------------------------------------------------------

Fields
Fields have a type and a value. The java.lang.reflect.Field class provides methods for accessing type information and setting and getting values of a field on a given object.

Obtaining Field Types describes how to get the declared and generic types of a field
Retrieving and Parsing Field Modifiers shows how to get portions of the field declaration such as public or transient
Getting and Setting Field Values illustrates how to access field values
Troubleshooting describes some common coding errors which may cause confusion
Methods
Methods have return values, parameters, and may throw exceptions. The java.lang.reflect.Method class provides methods for obtained the type information for the parameters and return value. It may also be used to invoke methods on a given object.

Obtaining Method Type Information shows how to enumerate methods declared in a class and obtains type information
Retrieving and Parsing Method Modifiers describes how to access and decode modifiers and other information associated with the method
Invoking Methods illustrates how to execute a method and obtain its return value
Troubleshooting covers common errors encountered when finding or invoking methods
Constructors
The Reflection APIs for constructors are defined in java.lang.reflect.Constructor and are similar to those for methods, with two major exceptions: first, constructors have no return values; second, the invocation of a constructor creates a new instance of an object for a given class.

Finding Constructors illustrates how to retrieve constructors with specific parameters
Retrieving and Parsing Constructor Modifiers shows how to obtain the modifiers of a constructor declaration and other information about the constructor
Creating New Class Instances shows how to instantiate an instance of an object by invoking its constructor
Troubleshooting describes common errors which may be encountered while finding or invoking constructors

Obtaining Field Types
A field may be either of primitive or reference type. There are eight primitive types: boolean, byte, short, int, long, char, float, and double. A reference type is anything that is a direct or indirect subclass of java.lang.Object including interfaces, arrays, and enumerated types.

The FieldSpy example prints the field's type and generic type given a fully-qualified binary class name and field name.


import java.lang.reflect.Field;
import java.util.List;

public class FieldSpy<T> {
    public boolean[][] b = {{ false, false }, { true, true } };
    public String name  = "Alice";
    public List<Integer> list;
    public T val;

    public static void main(String... args) {
            try {
                Class<?> c = Class.forName(args[0]);
                Field f = c.getField(args[1]);
                System.out.format("Type: %s%n", f.getType());
                System.out.format("GenericType: %s%n", f.getGenericType());

        // production code should handle these exceptions more gracefully
            } catch (ClassNotFoundException x) {
                x.printStackTrace();
            } catch (NoSuchFieldException x) {
                x.printStackTrace();
            }
    }
}

Sample output to retrieve the type of the three public fields in this class (b, name, and the parameterized type list), follows. User input is in italics.
$ java FieldSpy FieldSpy b
Type: class [[Z
GenericType: class [[Z
$ java FieldSpy FieldSpy name
Type: class java.lang.String
GenericType: class java.lang.String
$ java FieldSpy FieldSpy list
Type: interface java.util.List
GenericType: java.util.List<java.lang.Integer>
$ java FieldSpy FieldSpy val
Type: class java.lang.Object
GenericType: T

The type for the field b is two-dimensional array of boolean. The syntax for the type name is described in Class.getName().

The type for the field val is reported as java.lang.Object because generics are implemented via type erasure which removes all information regarding generic types during compilation. Thus T is replaced by the upper bound of the type variable, in this case, java.lang.Object.

Field.getGenericType() will consult the Signature Attribute in the class file if it's present. If the attribute isn't available, it falls back on Field.getType() which was not changed by the introduction of generics. The other methods in reflection with name getGenericFoo for some value of Foo are implemented similarly.


Retrieving and Parsing Field Modifiers
There are several modifiers that may be part of a field declaration:
Access modifiers: public, protected, and private
Field-specific modifiers governing runtime behavior: transient and volatile
Modifier restricting to one instance: static
Modifier prohibiting value modification: final
Annotations
The method Field.getModifiers() can be used to return the integer representing the set of declared modifiers for the field. The bits representing the modifiers in this integer are defined in java.lang.reflect.Modifier.

The FieldModifierSpy example illustrates how to search for fields with a given modifier. It also determines whether the located field is synthetic (compiler-generated) or is an enum constant by invoking Field.isSynthetic() and Field.isEnumCostant() respectively.


import java.lang.reflect.Field;
import java.lang.reflect.Modifier;
import static java.lang.System.out;

enum Spy { BLACK , WHITE }

public class FieldModifierSpy {
    volatile int share;
    int instance;
    class Inner {}

    public static void main(String... args) {
            try {
                Class<?> c = Class.forName(args[0]);
                int searchMods = 0x0;
                for (int i = 1; i < args.length; i++) {
                        searchMods |= modifierFromString(args[i]);
                }

                Field[] flds = c.getDeclaredFields();
                out.format("Fields in Class '%s' containing modifiers:  %s%n",
                               c.getName(),
                               Modifier.toString(searchMods));
                boolean found = false;
                for (Field f : flds) {
                        int foundMods = f.getModifiers();
                        // Require all of the requested modifiers to be present
                        if ((foundMods & searchMods) == searchMods) {
                            out.format("%-8s [ synthetic=%-5b enum_constant=%-5b ]%n",
                                           f.getName(), f.isSynthetic(),
                                           f.isEnumConstant());
                            found = true;
                        }
                }

                if (!found) {
                        out.format("No matching fields%n");
                }

        // production code should handle this exception more gracefully
            } catch (ClassNotFoundException x) {
                x.printStackTrace();
            }
    }

    private static int modifierFromString(String s) {
            int m = 0x0;
            if ("public".equals(s))           m |= Modifier.PUBLIC;
            else if ("protected".equals(s))   m |= Modifier.PROTECTED;
            else if ("private".equals(s))     m |= Modifier.PRIVATE;
            else if ("static".equals(s))      m |= Modifier.STATIC;
            else if ("final".equals(s))       m |= Modifier.FINAL;
            else if ("transient".equals(s))   m |= Modifier.TRANSIENT;
            else if ("volatile".equals(s))    m |= Modifier.VOLATILE;
            return m;
    }
}

Sample output follows:

$ java FieldModifierSpy FieldModifierSpy volatile
Fields in Class 'FieldModifierSpy' containing modifiers:  volatile
share    [ synthetic=false enum_constant=false ]
$ java FieldModifierSpy Spy public
Fields in Class 'Spy' containing modifiers:  public
BLACK    [ synthetic=false enum_constant=true  ]
WHITE    [ synthetic=false enum_constant=true  ]
$ java FieldModifierSpy FieldModifierSpy\$Inner final
Fields in Class 'FieldModifierSpy$Inner' containing modifiers:  final
this$0   [ synthetic=true  enum_constant=false ]
$ java FieldModifierSpy Spy private static final
Fields in Class 'Spy' containing modifiers:  private static final
$VALUES  [ synthetic=true  enum_constant=false ]

Notice that some fields are reported even though they are not declared in the original code. This is because the compiler will generate some synthetic fields which are needed during runtime. To test whether a field is synthetic, the example invokes Field.isSynthetic(). The set of synthetic fields is compiler-dependent; however commonly used fields include this$0 for inner classes (i.e. nested classes that are not static member classes) to reference the outermost enclosing class and $VALUES used by enums to implement the implicitly defined static method values(). The names of synthetic class members are not specified and may not be the same in all compiler implementations or releases. These and other synthetic fields will be included in the array returned by Class.getDeclaredFields() but not identified by Class.getField() since synthetic members are not typically public.

Because Field implements the interface java.lang.reflect.AnnotatedElement, it is possible to retrieve any runtime annotation with java.lang.annotation.RetentionPolicy.RUNTIME. For an example of obtaining annotations see the section Examining Class Modifiers and Types.