Java Reflection tutorial

Introduction

Reflection, as we know from the common term, is an image of yourself or something else you see in a mirror or a mirrored surface. Java, being an object-oriented language draws heavily from real-life examples and so is the Reflection API of Java inspired from real life.

In Java, the process of analyzing, viewing and modifying all the internal attributes, behaviors and capabilities of a class at runtime is called Reflection. Using the concept of Reflection, a programmer can now manipulate all attributes of a class – including its methods, constructors, and fields even at runtime, and even invoke methods of that class and get a complete snapshot of it.

Reflection is heavily used in Java frameworks such as Spring, Hibernate, Junit etc.

The ‘reflect’ package

The core collection of classes and information related to Reflection in Java is encapsulated as the java.lang.reflect package. It contains several interfaces and classes which define methods that are used for reflection of other classes.

Let us have a look at some of the classes within the java.lang.reflect package

Field

This class provides information about the fields present in the class whose reflection is being looked at.

Modifier

This class provides information about the class and other members’ access modifiers of the class being reflected.

Proxy

This class supports the dynamic proxy classes

Method

This class provides information about the methods of the class being reflected and inspected.

Constructor

This class provides information regarding the constructors of the class being reflected and inspected.

Array

This class allows the programmer to dynamically create and manipulate Arrays

Other than these, the java.lang.Class class is one of the most important classes in use for Reflection as the objects of Class can store the actual information of the class that we want to investigate or reflect.

Uses of Reflection in Java

Extensibility

Using the concepts of reflection, a programmer can make use of externally available user-defined classes by creating instances of those extensible objects by using their fully qualified name

Developing IDEs and Class Browsers

IDEs, especially those which are capable of visual development, such as Eclipse or Netbeans, and class browsers can make extensive use of Reflection. Using these, the visual development environments make the information of the classes readily available to the user so that they can write proper code.

Debugging and Testing tools

Debugging requires the ability to view internal details of a class which include its private members.Debugging and Testing tools may use reflection to make systematic invocations to the classes by use of reflection and ensure test case coverage.

Disadvantages of Reflection

Inspite of being an extremely powerful tool, Reflection API and its usage does have a set of disadvantages such as,

Low Performace

The use of reflection API can lead to high performance overhead and lead to lower performance. This is because many functionalities make use of dynamic resolution which prevents to the use of certain Virtual machine optimisations. As it tends to slow down processing, it isn’t recommended for use in sections of code that require high availability and low turnaround.

Security Risk

Reflection API requires cetain security permissions that are not available during execution under a securely managed system. Also, the security permission requirements can pose a threat to code residing in a secure system.

Exposure of Internal Fields and Attributes

Due to the ability of Reflection API to access private members and invoke private functions, the internal details of classes and entities are exposed to the outside world and defeats the purpose of Abstraction in object oriented concepts, which may be seen as a violation of object oriented programming concepts.

Now that we have had an overview of the basic idea of Reflection, let us go through the java.lang.Class class which plays the most significant role in reflection in java.

Java.lang.Class – the gateway to Reflection

The Class is a final class in the java.lang package of Java’s standard library, and extends the Object class which forms the basis of all classes in java. An instance of the class Class is used to represent both classes and interfaces in a Java application which is running. Using an instance of Class, we can view, analyse and modify the attributes of a class while it is running, and can even invoke methods of that class.

Important Methods of java.lang.Class

The Class class has a wide variety of methods that are useful in obtaining a reflection of the class executing and performing a wide range of actions with that class. Some of these methods are:

forName() method:

This method accepts the full qualified name of a class or an interface as an argument and returns an instance of the class associated with the qualifed name, including all its attributes and behaviours.

The syntax for the forName method is as follows:

Let us see an example of the forName method:

The above code generates the following output:

TestClass

getConstructors() and getDeclaredConstructors() methods:

The getConstructors() method returns an array of the declared public constructors of the invoking object in the form of java.lang.reflect.Constructor objects. The getDeclaredConstructors() method returns all the constructors of the invoking object including non-public members.

The syntax for both getConstructors() and getDeclaredConstructors() are as follows:

Let us see an example of the use of the above methods:

The above code on execution produces the following output:

Using getConstructors()
public org.arpit.java2blog.TestClass()
====================
Using getDeclaredConstructors()
public org.arpit.java2blog.TestClass()
protected org.arpit.java2blog.TestClass(java.lang.Integer)

getMethods() and getDeclaredMethods()

The getMethods() function of java.lang.Class returns an array of java.lang.reflect.Method instances that reflect and return all the public methods of the invoking object. On the other hand, the getDeclaredMethods() function returns only the methods declared by the programmer.

The syntax for both functions are as follows:

Let us see an example of the use of the above methods:

The above code on execution produces the following result:

==================
Using getMethods()
==================
public void org.arpit.java2blog.TestClass2.put()
public final void java.lang.Object.wait(long,int) throws java.lang.InterruptedException
public final native void java.lang.Object.wait(long) throws java.lang.InterruptedException
public final void java.lang.Object.wait() throws java.lang.InterruptedException
public boolean java.lang.Object.equals(java.lang.Object)
public java.lang.String java.lang.Object.toString()
public native int java.lang.Object.hashCode()
public final native java.lang.Class java.lang.Object.getClass()
public final native void java.lang.Object.notify()
public final native void java.lang.Object.notifyAll()
===========================
Using getDeclaredMethods()
============================
public void org.arpit.java2blog.TestClass2.put()
protected int org.arpit.java2blog.TestClass2.show()

Thus you can see that the getMethods() method returns all the public methods of the object including superclasses, whereas getDeclaredMethods() only returned user-declared methods.

getFields() and getDeclaredFields() methods:

The getFields() methods returns an array consisting of java.lang.Field objects which display all the public attributes of the invoking class or interface. On the other hand, the getDeclaredFields() method returns an array of Field objects which represent all the fields declkared in the invoking class or interface.

The syntax of the methods are as follows:

Let us see an example of the above methods:

The above code produces the following result on execution.

Using getFields() method
=======================
public int org.arpit.java2blog.TestClass.a
=======================
Using getDeclaredFields() method
=======================
public int org.arpit.java2blog.TestClass.a
java.lang.String org.arpit.java2blog.TestClass.b

Conclusion

Java’s greatest positives is that the design of Java was made such as to encapsulate a diversely dynamic environment – Classes are loaded dynamically, methods are bound dynamically, variables are created dynamically. This led to the idea of manipulating the classes and viewing them dynamically which materialized as the Reflection API of Java. Reflection helps to make Java a dynamic language that further enhances the benefits of the language.

Was this post helpful?

Leave a Reply

Your email address will not be published. Required fields are marked *