In this tutorial, you’ll learn about reflection, a Java feature that allows us to inspect and modify classes, methods, and other objects.
Contents
What is reflection in Java?
The Java programming language has a feature called reflection. It allows a Java program in execution to examine or “introspect” itself and manipulate its internal properties. A Java class, for example, can get the names of all its members and display them.
Reflection in Java allows us to inspect and manipulate classes, interfaces, constructors, methods, and fields while they are running.
In Java, there’s a class called Class that keeps track of all the data about objects and classes at runtime. Reflection can be performed on the Class object.
Reflection is a runtime API for inspecting and changing the behaviour of methods, classes, and interfaces.
- The java.lang.reflect package contains the necessary reflection classes.
- Reflection informs us about the class to which an object belongs, as well as the methods of that class that can be used with the object.
- We can call methods at runtime using reflection, regardless of the access specifier used.
Where is Reflection used?
Java’s Reflection API is primarily used in:
- Integrated Development Environments (IDEs) like Eclipse, MyEclipse, NetBeans, and others.
- Tools for Debugger Testing
Commonly used methods of Class :
Method | Description |
---|---|
1) public String getName() | returns the name of the class |
2) public static Class forName(String className)throws ClassNotFoundException | The class is loaded and the reference to the Class class is returned. |
3) public Object newInstance()throws InstantiationException,IllegalAccessException | creates a new instance |
4) public boolean isArray() | checks if it is array. |
5) public Class getSuperclass() | The superclass class reference is returned. |
6) public Field[] getDeclaredFields()throws SecurityException | The total number of fields in this class is returned. |
7) public Method[] getDeclaredMethods()throws SecurityException | The total number of methods in this class is returned. |
8) public Constructor[] getDeclaredConstructors()throws SecurityException | The total number of constructors in this class is returned. |
9) public Method getDeclaredMethod(String name,Class[] parameterTypes)throws NoSuchMethodException,SecurityException | The method class instance is returned. |
Reflection of Java Classes
We must first create a Class object in order to reflect a Java class. We can also use the object to call various methods to get information about a class’s methods, fields, and constructors.
There are three methods for creating Class objects:
1:Using forName() method
The name of the class to be reflected is passed as an argument to the forName() method.
- The forName() method dynamically or at runtime loads the class. This method returns a Class class instance. We should only use it if we know the class’s fully qualified name. We can’t call primitive types by this name.
- Let’s look at an example of using the forName() method to retrieve a class instance:
class Demo {…} // create object of Class
// to reflect the Demo class
Class a = Class.forName(“Demo”);
2: Using getClass() method
- The getClass() method is part of the Object class, and it returns a Class instance. When we know the type, we should use it. It can also be applied to primitives.
- We’re going to make a Class object out of an object from the Demo class.
// create an object of Dog class
Demo d = new Demo(); // create an object of Class
// to reflect Demo
Class b = d.getClass();
3: Using .class extension
There are times when a type is available but no instance of the class is present. In such cases, the Class can be obtained by appending the.class syntax to the type’s name. This syntax can also be used with primitives.
Now that we’ve learned how to make Class objects, let’s move on to the next step. At runtime, we can use this object to obtain information about the corresponding class.
// create an object of Class
// to reflect the Dog class
Class c = Demo.class;
Example: Java Class Reflection
import java.lang.Class; import java.lang.reflect.*; class Sample { } // put this class in different Demo.java file public class Demo extends Sample { public void display() { System.out.println("I am a Demo"); } } // put this in Main.java file class Main { public static void main(String[] args) { try { // create an object of Demo Demo d = new Demo(); // create an object of Class // using getClass() Class obj = d.getClass(); // get name of the class String name = obj.getName(); System.out.println("Name: " + name); // get the access modifier of the class int modifier = obj.getModifiers(); // convert the access modifier to string String mod = Modifier.toString(modifier); System.out.println("Modifier: " + mod); // get the superclass of Demo Class superClass = obj.getSuperclass(); System.out.println("Superclass: " + superClass.getName()); } catch (Exception e) { e.printStackTrace(); } } }
Output:
Name: Demo
Modifier: public
Superclass: Sample
- We’ve created a superclass called Sample and a subclass called Demo in the example above. We’re attempting to inspect the Demo class here.
- Take note of the statement:
Class obj = d1.getClass();
The getClass() method is used to create an object obj of Class. We’re using the object to call various Class methods.
- obj.getName() returns the class’s name.
- obj.getModifiers() returns the class’s access modifier.
- obj.getSuperclass() returns the class’s super class.
Gathering Data Using the Reflection API
We can use Reflection to learn more about:
- Class: The getClass() method returns the class name to which an object belongs.
- Constructors: The getConstructors() method returns all of the class’s public constructors.
- Methods: The getMethods() method returns all of the public methods of the class that an object belongs to.
1. Reflection of Java Methods
The Method class contains a number of methods that can be used to obtain information about the methods in a class. As an example:
import java.lang.Class; import java.lang.reflect.*; class Demo { // methods of the class public void display() { System.out.println("I am a Demo"); } private quiz() { System.out.println("Quiz..."); } } class Main { public static void main(String[] args) { try { // create an object of Demo Demo d = new Demo(); // create an object of Class // using getClass() Class obj = d.getClass(); // using object of Class to // get all the declared methods of Demo Method[] methods = obj.getDeclaredMethods(); // create an object of the Method class for (Method m : methods) { // get names of methods System.out.println("Method Name: " + m.getName()); // get the access modifier of methods int modifier = m.getModifiers(); System.out.println("Modifier: " + Modifier.toString(modifier)); // get the return types of method System.out.println("Return Types: " + m.getReturnType()); System.out.println(" "); } } catch (Exception e) { e.printStackTrace(); } } }
Output
Method Name: display
Modifier: public
Return Types: void Method Name: quiz
Modifier: private
Return Types: void
In the preceding example, we are attempting to obtain information about the methods available in the Demo class. As previously stated, we first used the getClass() method to create an object obj of Class.
Take note of the expression.
Method[] methods = obj.getDeclaredMethod();
In this case, getDeclaredMethod() returns all of the methods contained within the class.
We’ve also created an object m of the Method class. Here,
- m.getName() – returns the method name.
- m.getModifiers() – returns the method access modifier in integer form.
- m.getReturnType() – returns the method’s return type.
2. Reflection of Java Fields
Using the Field class’s methods, we can inspect and modify various fields of a class, just like methods. As an example:
import java.lang.Class; import java.lang.reflect.*; class Demo { public String type; } class Main { public static void main(String[] args) { try { // create an object of Demo Demo d = new Demo(); // create an object of Class // using getClass() Class obj = d.getClass(); // access and set the type field Field field1 = obj.getField("type"); field1.set(d, "Quiz"); // get the value of the field type String typeValue = (String) field1.get(d); System.out.println("Value: " + typeValue); // get the access modifier of the field type int mod = field1.getModifiers(); // convert the modifier to String form String modifier1 = Modifier.toString(mod); System.out.println("Modifier: " + modifier1); System.out.println(" "); } catch (Exception e) { e.printStackTrace(); } } }
Output
Value: quiz
Modifier: public
In the preceding example, we created a class called Demo. It has a public field called type. Take note of the statement:
Field field1 = obj.getField(“type”);
In this case, we’re accessing the public field of the Demo class and assigning it to the Field class’s object field1.
Then we used the Field class’s various methods:
- field1.set() – sets the field’s value field1.get() – returns the field’s value field1.getModifiers() – returns the field’s value in integer form
3. Reflection of Java Constructor
We can also inspect different constructors of a class using the Constructor class’s various methods. As an example:
import java.lang.Class; import java.lang.reflect.*; class Demo { // public constructor without parameter public Demo() { } // private constructor with a single parameter private Demo(int age) { } } class Main { public static void main(String[] args) { try { // create an object of Demo Demo d = new Demo(); // create an object of Class // using getClass() Class obj = d.getClass(); // get all constructors of Demo Constructor[] constructors = obj.getDeclaredConstructors(); for (Constructor c : constructors) { // get the name of constructors System.out.println("Constructor Name: " + c.getName()); // get the access modifier of constructors // convert it into string form int modifier = c.getModifiers(); String mod = Modifier.toString(modifier); System.out.println("Modifier: " + mod); // get the number of parameters in constructors System.out.println("Parameters: " + c.getParameterCount()); System.out.println(""); } } catch (Exception e) { e.printStackTrace(); } } }
Output
Constructor Name: Demo
Modifier: public
Parameters: 0
Constructor Name: Demo
Modifier: private
Parameters: 1
In the preceding example, we created a class called Dog. There are two constructors in the class. We’re using reflection to learn more about the class’s constructors. Take note of the statement:
Constructor[] constructors = obj.getDeclaredConstructor();
- In this case, we are accessing all of the constructors in Demo and assigning them to an array of Constructor constructors.
- We then used object c to obtain various constructor-related information.
- c.getName() returns the constructor’s name; c.getModifiers() returns the constructor’s access modifiers in integer form; and c.getParameterCount() returns the number of parameters present in each constructor.
Advantages and Disadvantages of reflection
Advantages | Disadvantages |
---|---|
Reflection allows you to inspect interfaces, classes, methods, and fields during runtime without having to use their names during compile time. Reflection can also be used to call methods, create a clear, and set the value of fields. It aids in the development of Visual Development Environments (VDEs) and class browsers, which assist developers in writing correct code. | 1: The principles of encapsulation can be broken by using reflection. Reflection can be used to gain access to a class’s private methods and fields. As a result, reflection may expose sensitive information to the outside world, which is dangerous. For example, if one user accesses a class’s private members and sets a null value to them, another user of the same class may receive a NullReferenceException, which is not expected. 2: Another flaw is the performance overhead. JVM (Java Virtual Machine) optimization is not possible because the types in reflection are resolved dynamically. As a result, the operations that reflections perform are typically slow. |
Summary
As a result, we have a complete understanding of the concept of reflection in Java after reading this article. We also talked about the classes and methods in Java that are used for reflection. Along with that, we talked about the benefits and drawbacks of Java Reflection. We learned how to retrieve the class’s name, interfaces, methods, and constructors. Using the reflection API, we can quickly obtain information about the class.
- Because of the disadvantages listed above, it is generally recommended that you avoid using reflection. It’s an advanced feature that should only be used by programmers or developers who are familiar with the language’s fundamentals. Always keep in mind! When reflection is used, the application’s security is put at risk.
You may like:
Java enum Constructor with Example
Java Inheritance with Example | Types of inheritance
Java final Keyword with Example
Java Polymorphism with Example
Singleton Class in Java with Implementation and Example
Java Nested and Inner Class with Example
Hope this article will guide you to recognize all about Java Reflection with Example that you needed and still if you have any problem or queries regarding this, post them in the comments section and we will be glad to assist you.