This Video Tutorial Explains what is Reflection and how to Implement it using Reflection API:
Reflection in Java is to inspect and change the behavior of a program at runtime.
With the help of this reflection API, you can inspect classes, constructors, modifiers, fields, methods, and interfaces at runtime. For Example, you can get the name of the class or you can get details of the private members of the class.
Read through our entire JAVA training series for more insight on Java concepts.
Here is a Video Tutorial on Java Reflection:
Table of Contents:
Reflection In Java
We are aware that in a given class we can modify its properties and methods at compile time and it is very easy to do so. Whether the properties and methods are anonymous or have names, they can be changed at our will during compile time.
But we cannot change these classes or methods or fields at runtime on the fly. In other words, it is very difficult to change the behavior of various programming components at runtime especially for unknown objects.
Java programming language provides a feature called “Reflection” that allows us to modify the runtime behavior of a class or field or method at runtime.
Thus a Reflection can be defined as a “technique of inspecting and modifying the runtime behavior of an unknown object at run time. An object can be a class, a field, or a method.”
Reflection is an “Application Programming Interface” (API) provided by Java.
The “Reflection” process is depicted below.
In the above representation, we can see that we have an unknown object. Then we use the Reflection API on this object. As a result, we can modify the behavior of this object at runtime.
Thus we can use Reflection API in our programs for the purpose of modifying the object’s behavior. The objects can be anything like methods, interfaces, classes, etc. We inspect these objects and then change their behavior at runtime using reflection API.
In Java, the “java.lang” and “java.lang.reflect” are the two packages that provide classes for reflection. The special class “java.lang.Class” provides the methods and properties to extract metadata using which we can inspect and modify the class behavior.
We use Reflection API provided by the above packages to modify the class and its members including fields, methods, constructors, etc. at runtime. A distinguishing feature of Reflection API is that we can also manipulate the private data members or methods of the class.
The Reflection API is mainly used in:
- Reflection is mainly used in debugging tools, JUnit, and frameworks to inspect and change the behavior at runtime.
- IDE (Integrated Development Environment) E.g. Eclipse IDE, NetBeans, etc.
- Test Tools etc.
- It is used, when your application has third-party libraries and when you want to know about the classes and methods available.
Reflection API In Java
Using Reflection API, we can implement the reflection on the following entities:
- Field: The Field class has information that we use to declare a variable or a field like a datatype (int, double, String, etc.), access modifier (private, public, protected, etc.), name (identifier) and value.
- Method: The Method class can help us to extract information like access modifier of the method, method return type, method name, method parameter types, and exception types raised by the method.
- Constructor: Constructor class gives information about class constructor that includes constructor access modifier, constructor name, and parameter types.
- Modifier: Modifier class gives us information about a specific access modifier.
All the above classes are a part of java.lang.reflect package. Next, we will discuss each of these classes and use programming examples to demonstrate the reflection on these classes.
Let’s first start with the class java.lang.Class.
java.lang.Class Class
The java.lang.The class holds all the information and data about classes and objects at runtime. This is the main class used for reflection.
The class java.lang.Class provides:
- Methods to retrieve class metadata at run time.
- Methods to inspect and modify the behavior of a class at run time.
Create java.lang.Class Objects
We can create objects of java.lang.Class using one of the following options.
#1) .class extension
The first option to create an object of Class is by using the .class extension.
For example, if Test is a class, then we can create a Class object as follows:
Class obj_test = Test.class;
Then we can use the obj_test to perform reflection as this object will have all the information about the class Test.
#2) forName() method
forName () method takes the name of the class as an argument and returns the Class object.
For example, the object of the Test class can be created as follows:
class obj_test = Class.forName (“Test”);
#3) getClas () method
getClass() method uses object of a class to get the java.lang.Class object.
For example, consider the following piece of code:
Test obj = new Test (); Class obj_test = obj.getClass ();
In the first line, we created an object of Test class. Then using this object we called the “getClass ()” method to get an object obj_test of java.lang.Class.
Get Super Class & Access Modifiers
java.lang.class provides a method “getSuperClass()” that is used to get the superclass of any class.
Similarly, it provides a method getModifier() that returns the access modifier of the class.
The below example demonstrates the getSuperClass() method.
import java.lang.Class; import java.lang.reflect.*; //define Person interface interface Person { public void display(); } //declare class Student that implements Person class Student implements Person { //define interface method display public void display() { System.out.println("I am a Student"); } } class Main { public static void main(String[] args) { try { // create an object of Student class Student s1 = new Student(); // get Class object using getClass() Class obj = s1.getClass(); // get the superclass of Student Class superClass = obj.getSuperclass(); System.out.println("Superclass of Student Class: " + superClass.getName()); } catch(Exception e) { e.printStackTrace(); } } }
Output
In the above programming example, an interface Person is defined with a lone method ‘display ()’. Then we define a Student class implementing the person interface. In the main method, we use the getClass () method to retrieve the Class object and then access the parent or superclass of Student object using the getSuperClass () method.
Get Interfaces
If the class implements some interfaces, then we can get these interfaces names using the getInterfaces() method of the java.lang.Class. For this, we have to perform a reflection on the Java class.
The below programming example depicts the use of the getInterfaces () method in Java Reflection.
import java.lang.Class; import java.lang.reflect.*; //define Interface Animals and PetAnimals interface Animals { public void display(); } interface PetAnimals { public void makeSound(); } //define a class Dog that implements above interfaces class Dog implements Animals, PetAnimals { //define interface method display public void display() { System.out.println("This is a PetAnimal::Dog"); } //define interface method makeSound public void makeSound() { System.out.println("Dog makes sound::Bark bark"); } } class Main { public static void main(String[] args) { try { // create an object of Dog class Dog dog = new Dog(); // get class object Class obj = dog.getClass(); // get the interfaces implemented by Dog Class[] objInterface = obj.getInterfaces(); System.out.println("Class Dog implements following interfaces:"); //print all the interfaces implemented by class Dog for(Class citem : objInterface) { System.out.println("Interface Name: " + citem.getName()); } } catch(Exception e) { e.printStackTrace(); } } }
Output
In the above program, we have defined two interfaces i.e. Animals and PetAnimals. Then we define a class Dog, that implements both these interfaces.
In the main method, we retrieve the object of class Dog in java.lang.Class to perform reflection. Then we use the getInterfaces () method to retrieve the interfaces that are implemented by the class Dog.
Reflection: Get Field Value
As already mentioned the package java.lang.reflect provides the Field class that helps us to reflect the field or data members of the class.
Enlisted below are the methods provided by the Field class for Reflection of a field.
Method | Description |
---|---|
getFields() | Returns all the public fields (both for class & superclass). |
getDeclaredFields() | Retrieves all the fields of the class. |
getModifier() | Returns integer representation of access modifier of the field. |
set(classObject, value) | Assigns the specified value to the field. |
get(classObject) | Retrieves field value. |
setAccessible(boolean) | Make private field accessible by passing true. |
getField("fieldName") | Returns the field (public) with a specified field name. |
getDeclaredField("fieldName") | Returns the field with a specified name. |
Given below are two reflection examples that demonstrate the reflection on the public and private field.
The Java program below demonstrates the reflection on a public field.
import java.lang.Class; import java.lang.reflect.*; class Student { public String StudentName; } class Main { public static void main(String[] args) { try{ Student student = new Student(); // get an object of the class Class Class obj = student.getClass(); // provide field name and get the field info Field student_field = obj.getField("StudentName"); System.out.println("Details of StudentName class field:"); // set the value of field student_field.set(student, "Lacey"); // get the access modifier of StudentName int mod1 = student_field.getModifiers(); String modifier1 = Modifier.toString(mod1); System.out.println("StudentName Modifier::" + modifier1); // get the value of field by converting in String String typeValue = (String)student_field.get(student); System.out.println("StudentName Value::" + typeValue); } catch(Exception e) { e.printStackTrace(); } } }
Output
In this program, we have declared a class “Student” having a public field StudentName. Then using the API interface of the Field class, we perform reflection on the field StudentName and retrieve its access modifier and value.
The next program performs reflection on a private field of the class. The operations are similar except that there is one extra function call made for the private field. We have to call setAccessible (true) for the private field. Then we perform reflection on this field in a similar manner as the public field.
import java.lang.Class; import java.lang.reflect.*; class Student { private String rollNo; } class Main { public static void main(String[] args) { try { Student student = new Student(); // get the object for class Student in a Class. Class obj = student.getClass(); // access the private field Field field2 = obj.getDeclaredField("rollNo"); // make the private field accessible field2.setAccessible(true); // set the value of rollNo field2.set(student, "27"); System.out.println("Field Information of rollNo:"); // get the access modifier of rollNo int mod2 = field2.getModifiers(); String modifier2 = Modifier.toString(mod2); System.out.println("rollNo modifier::" + modifier2); // get the value of rollNo converting in String String rollNoValue = (String)field2.get(student); System.out.println("rollNo Value::" + rollNoValue); } catch(Exception e) { e.printStackTrace(); } } }
Output
Reflection: Method
Similar to the fields of the class, we can also perform reflection on class methods and modify their behavior at run time. For this, we use the Method class of java.lang.reflect package.
Enlisted below are the functions provided by the Method class for Reflection of the class method.
Method | Description |
---|---|
getMethods() | Retrieves all public methods defined in the class and its superclass. |
getDeclaredMethod() | Returns methods declared in the class. |
getName() | Returns the method names. |
getModifiers() | Returns integer representation of method’s access modifier. |
getReturnType() | Returns the method return type. |
The below example shows the reflection of class methods in Java using the above APIs.
import java.lang.Class; import java.lang.reflect.*; //declare a class Vehicle with four methods class Vehicle { public void display() { System.out.println("I am a Vehicle!!"); } protected void start() { System.out.println("Vehicle Started!!!"); } protected void stop() { System.out.println("Vehicle Stopped!!!"); } private void serviceVehicle() { System.out.println("Vehicle serviced!!"); } }class Main { public static void main(String[] args) { try { Vehicle car = new Vehicle(); // create an object of Class Class obj = car.getClass(); // get all the methods using the getDeclaredMethod() in an array Method[] methods = obj.getDeclaredMethods(); // for each method get method info for(Method m : methods) { System.out.println("Method Name: " + m.getName()); // get the access modifier of methods int modifier = m.getModifiers(); System.out.print("Modifier: " + Modifier.toString(modifier) + " "); // get the return type of method System.out.print("Return Type: " + m.getReturnType()); System.out.println("\n"); } } catch(Exception e) { e.printStackTrace(); } } }
Output
In the above program, we see that the method getDeclaredMethods returns the array of methods declared by the class. Then we iterate through this array and display the information of each method.
Reflection: Constructor
We can use the “Constructor” class of java.lang.reflect package to inspect and modify the constructors of a Java class.
The constructor class provides the following methods for this purpose.
Method | Description |
---|---|
getConstructors() | Returns all the constructors declared in class and its superclass. |
getDeclaredConstructor() | Returns all the declared constructors. |
getName() | Retrieves the name of the constructor. |
getModifiers() | Returns the integer representation of access modifier of constructors. |
getParameterCount() | Returns the total number of parameters for a constructors. |
The reflection example below demonstrates the reflection of constructors of a class in Java. Like method reflection, here also getDeclaredConstructors method returns an array of constructors for a class. Then we traverse through this constructor array to display information about each constructor.
import java.lang.Class; import java.lang.reflect.*; //declare a class Person with three constructors class Person { public Person() { } //constructor with no parameters public Person(String name) { } //constructor with 1 parameter private Person(String name, int age) {} //constructor with 2 parameters } class Main { public static void main(String[] args) { try { Person person = new Person(); Class obj = person.getClass(); // get array of constructors in a class using getDeclaredConstructor() Constructor[] constructors = obj.getDeclaredConstructors(); System.out.println("Constructors for Person Class:"); for(Constructor c : constructors) { // get names of constructors System.out.println("Constructor Name: " + c.getName()); // get access modifier of constructors int modifier = c.getModifiers(); System.out.print ("Modifier: " + Modifier.toString(modifier) + " "); // get the number of parameters in constructors System.out.println("Parameters: " + c.getParameterCount()); //if there are parameters, get parameter type of each parameter if(c.getParameterCount() > 0){ Class[] paramList=c.getParameterTypes(); System.out.print ("Constructor parameter types :"); for (Class class1 : paramList) { System.out.print(class1.getName() +" "); } } System.out.println("\n"); } } catch(Exception e) { e.printStackTrace(); } } }
Output
Drawbacks Of Reflection
Reflection is powerful, but should not be used indiscriminately. If it is possible to operate without using reflection, then it is preferable to avoid using it.
Enlisted below are few drawbacks of Reflection:
- Performance Overhead: Though reflection is a powerful feature, reflective operations still have slower performance than non- reflective operations. Hence we should avoid using reflections in performance-critical applications.
- Security Restrictions: As reflection is a runtime feature, it might require run-time permissions. So for the applications that require the code to be executed in a restricted security setting, then reflection may be of no use.
- Exposure of Internals: By using reflection, we can access private fields and methods in a class. Thus reflection breaks abstraction that might render code unportable and dysfunctional.
Frequently Asked Questions
Q #1) Why is Reflection used in Java?
Answer: Using reflection we can inspect classes, interfaces, constructors, fields, and methods at runtime, even if they are anonymous at compile time. This inspection allows us to modify the behavior of these entities at runtime.
Q #2) Where is Reflection used?
Answer: Reflection is used in writing frameworks that interoperate with user-defined classes, wherein the programmer doesn’t even know what the classes or other entities will be.
Q #3) Is Java Reflection slow?
Answer: Yes, it is slower than the non-reflection code.
Q #4) Is Java Reflection bad?
Answer: In a way, yes. First of all, we lose compile-time safety. Without compile-time safety, we might get run time errors that may affect end users. It will also be difficult to debug the error.
Q #5) How do you stop a Reflection in Java?
Answer: We simply avoid using reflection by writing non-reflection operations. Or maybe we can use some generic mechanisms like a custom validation with reflection.
More About Java Reflection
java.lang.reflect package has the classes and interfaces to do reflection. And the java.lang.class can be used as an entry point for the reflection.
How to get the class objects:
1. If you have instance of an object,
class c=obj.getclass();
2. If you know the type of the class,
class c =type.getClass();
3. If you know the class name,
Class c = Class.forName(“com.demo.Mydemoclass”);
How to get the class members:
Class members are fields (class variables) and methods.
- getFields() – Used to get all the fields except the private fields.
- getDeclaredField() – Used to get the private fields.
- getDeclaredFields() – Used to get the private and public fields.
- getMethods()– Used to get all the methods except the private methods.
- getDeclaredMethods() –Used to get the public and private methods.
Demo Programs:
ReflectionHelper.java:
This is the class where we are going to inspect using the reflection API.
class ReflectionHelper { private int age; private String name; public String deptName; public int empID; public int getAge() { return age; } public void setAge(int age) { this.age = age; } public String getName() { return name; } public void setName(String name) { this.name = name; } public String getDeptName() { return deptName; } public void setDeptName(String deptName) { this.deptName = deptName; } }
ReflectionDemo.java
public class ReflectionDemo { public static void main(String[] args) throws NoSuchFieldException, SecurityException { //get the class Class ReflectionHelperclass=ReflectionHelper.class; //get the name of the class String className = ReflectionHelperclass.getName(); System.out.println("className=="+className); System.out.println("getModifiers"+ReflectionHelperclass.getModifier s()); System.out.println("getSuperclass"+ReflectionHelperclass.getSupercla ss()); System.out.println("getPackage"+ReflectionHelperclass.getPackage()); Field[] fields =ReflectionHelperclass.getFields(); //getting only the public fields for(Field oneField : fields) { Field field = ReflectionHelperclass.getField(oneField.getName()); String fieldname = field.getName(); System.out.println("only the public fieldnames:::::"+fieldname); } //getting all the fields of the class Field[] privatefields =ReflectionHelperclass.getDeclaredFields(); for(Field onefield : privatefields) { Field field = ReflectionHelperclass.getDeclaredField(onefield.getName()); String fieldname = field.getName(); System.out.println("all the fieldnames in the class:::"+fieldname); } Method[] methods =ReflectionHelperclass.getDeclaredMethods(); for(Method m: methods) { System.out.println("methods::::"+m.getName()); } }}
Conclusion
This tutorial explained the Reflection API in Java in detail. We saw how to perform reflection of classes, interfaces, fields, methods, and constructors along with a few drawbacks of reflection.
Reflection is a relatively advanced feature in Java but should be used by programmers having a stronghold on the language. This is because it might cause unexpected errors and results if not used with caution.
Although reflection is powerful, it should be used carefully. Nonetheless, using reflection we can develop applications that are unaware of classes and other entities until runtime.
=> Take A Look At The Java Beginners Guide Here.