How to set field values using Java reflection
In the Java reflection API, the java.lang.reflect.Field class represents a generic field in a class or interface, and allows to retrieve programmatically field information, such as name, type, or annotations. In addition, via the Field class we can get and set the value of a field in a given object.
The most generic method to set a field value is set(Object obj, Object value): it takes as first argument the object on which the field needs to be set, and as second argument the value for the field. The above method can be used for any field type, either primitive or class type; in case of a primitive type, value must be an instance of the Java class corresponding to the type, such as java.lang.Integer, java.lang.Float, and so on. For primitive types, there also exist specific methods that can be called passing them directly primitive type values:
How to retrieve the fields of a Java class
The Java reflection API, i.e. the set of classes defined in the java.lang.reflect package, offers powerful tools to inspect at run-time the definition of any class used in a Java program. The usual starting point to inspect a class definition is acquiring a java.lang.Class instance representing a given class; it is easy to obtain such an instance because every class defines implicitly a public field called class that contains a reference to the Class object representing this class. Among other things, java.lang.Class allows retrieving the definition of all the accessible public fields of a given class: the method to call to do so is getFields(), which returns an array of java.lang.reflect.Field objects representing each of the (class or instance) fields.
The Field class represents a particular field defined in a class or interface, and contains various methods to get or set the field value, or to get static information such as field name and type. In the following example we will retrieve the name of a field, using the getName() method. The code first acquires the Class object corresponding to the java.lang.String class, then retrieves the fields of the String class with a call to getFields(), and finally prints the name of the first field.
How to retrieve the constructors of a Java class
In object-oriented programming, a class constructor is a method called every time an object of a given class is created. In Java, a class can have more than one constructor, and different constructors differ in the list of parameters they accept. The java.lang.Class<T> class, which contains the definition of an arbitrary T class, offers various methods to inspect a class; one of these methods is getConstructors(), which returns an array of java.lang.reflect.Constructor objects representing each of the public constructors of a given class.
The constructor class allows retrieving information about a given constructor method, such as its parameters, the type of exceptions it can throw, etc. In the following example we demonstrate how to obtain the name of a constructor for the java.lang.String class, by using the getName() method of the Constructor class:
How to retrieve field values using Java reflection
Values of public member fields in a Java object can be obtained (and are usually obtained) with the notation <objectName>.<fieldName>. But Java offers another possibility to do that: using the reflection API it is possible to retrieve a java.lang.reflect.Field object representing a given field and to call specific methods of the Field class to obtain field values. While this process is clearly not necessary in the majority of cases where programmers know a priori the definition of classes they are using in a given program, if such definition is not known (or is only partially known) until when the program is executed the reflection API represents a valuable tool for dealing with unknown classes.
Differently from the usual case where a class definition is available at build time, the fields of a given class accessed through the reflection API can have an arbitrary type, thus the Field class provides a number of methods to retrieve field values of different types; all of these methods take as their unique argument the object from which a field value has to be retrieved. Below are listed the methods that allow retrieving each Java primitive type:
How to invoke Java methods using reflection
In the Java reflection API, a method of a class or interface is represented by the java.lang.reflect.Method class. An object of this class can reflect either a class method or an instance method. The Method class allows not only retrieving information about a given method, such as its name, its parameter list, its return type, the exceptions it can throw, etc., but also invoking the method on a given object.
A Method object representing a method in a given class is retrieved from the corresponding java.lang.Class object, by calling either getMethods(), which returns an array of objects representing the public methods of the class, or getMethod(String name, Class<?>... parameterTypes), which takes as arguments the method name and the types of its parameters (in the order in which they are defined) and returns the object representing the requested method. Once this object has been retrieved, the method it represents can be invoked by calling invoke(Object obj, Object... args), which takes as arguments the object on which to invoke the method and the list of arguments (if any) to be passed to the method invocation, and returns the return value from the invocation.
The simple example below shoes how to call a method using reflection.
How to retrieve the component type of an array
In Java, every array is an object, regardless of whether array elements are objects or primitive types. As a consequence, every array has a corresponding java.lang.Class object, which can be retrieved by calling the getClass() method of java.lang.Object. From the Class object associated to an array, we can retrieve the type of array elements via the getComponentType()method, which returns the Class object representing the element type. Class objects can represent not only classes and interfaces, but also primitive types, so the getComponentType() method works for any array object; if the object on which this method is called does not represent an array, then the method returns null.
In the following example, we first declare two arrays, and then retrieve their component types and print them on the standard output.
How to retrieve Java interfaces by using the getInterfaces() method
In Java, an interface is a set of functionalities that an object of a given class is expected to implement. A class is said to implement an interface when it contains all the methods defined in the interface. An interface can extend another interface, thus there are hierarchies of interfaces similarly to class hierarchies. Differently from the single inheritance model characterizing relationships between classes, a class can implement more than one interface, and an interface can extend more than one interface.
The java.lang.Class class provides a method to retrieve the interfaces implemented in a given class. This method is called getInterfaces() and returns an array (possibly with zero length) of Class objects representing the different interfaces implemented by a given class. It is worth noting that Class objects can refer not only to Java classes, but also to interfaces. If a Class object represents an interface, calling getInterfaces() on it returns an array with all the interfaces extended by this interface.
How to identify array objects
In computer programs, arrays are useful to group and access multiple elements of the same type. In Java, arrays (both single- and multi-dimensional) can be created from either primitive types (such as int, float, etc.) or classes. Every array belongs to a class that contains information on the type of array elements and the number of dimensions; as with any other class, the Class object corresponding to an array can be retrieved with the getClass() method of the java.lang.Object class.
Given a Class object, we can check whether it corresponds to an array object with the isArray() method, which returns true for array objects and false otherwise. The following example demonstrates the use of this method. After creating an array of integer values and a String object, we retrieve the corresponding Class objects and then we call isArray() on these objects.
How to find the superclass name by using the getSuperclass() method
In Java, class hierarchies follow the single inheritance model, i.e. a class can have at most one superclass. The only class that does not have any superclass is java.lang.Object, while all other classes, including user-defined classes, derive (directly or indirectly) from Object. The java.lang.Class class provides a method, called getSuperclass(), to retrieve the direct superclass (i.e. the next class encountered when walking up the hierarchy) of a given class; this method returns a Class object representing the superclass of the Class object on which the method is called; if the method is called on the Object class, null is returned.
How to check whether a class has a no-argument constructor
The java.lang.Class<T> class can be used to instantiate Java objects without calling explicitly their class constructor. For example, we can load a class by specifying its fully qualified name (i.e. the class name preceded by the name of the package in which the class is defined), using the forName(String className) static method of Class. If the given class can be found by the class loader, this method returns a Class object corresponding to the given class, otherwise it throws a java.lang.ClassNotFoundException. To instantiate an object of the returned class, we can use the newInstance() method, which returns an object created with the default constructor, i.e. the no-argument constructor. If the class or its constructor are not accessible form the calling code, a java.lang.IllegalAccessException is thrown, and if the instantiation fails for other reasons (for example, if the class does not have a no-argument constructor), a java.lang.InstantiationException is thrown.