Java Reflection Tutorial
Java Reflection is the process of analyzing and modifying all the capabilities of a particular class at runtime. Reflection API in Java is used to manipulate class and its members which include fields, methods, constructor, etc. at runtime. One advantage of reflection API in Java is, it can manipulate private members of the class too. The java.lang.reflect package provides many classes to implement reflection java. Methods of the java.lang.Class class is used to gather the complete metadata of a particular class.
Internal details of a class or interface:
- Finding the name of the package in which class or interface presents.
- Finding whether the .class file is class definition or interface definition.
- Finding Modifiers (Public, abstract, final) of a class or a interface.
- Finding the name of the base class for the current class.
- Finding the name of the base interface for the current class.
- Finding the number of data members in a class.
- Finding number of constructors in a class.
- Finding number of methods in a class.
- Finding the number of data members in an interface.
- Finding number of methods in an interface.
- Finding the names of the base interfaces for the current interface.
- Finding logical/simple name of class name and interface name.
Following is a list of various Java classes in java.lang.package to implement reflection-
1. java.lang.reflect.Field: This class is used to gather declarative information such as datatype, access modifier, name and value of a variable.
2. java.lang.reflect.Method: This class is used to gather declarative information such as access modifiers, return type, name, parameter types and exception type of a method.
3. java.lang.reflect.Constructor: This class is used to gather declarative information such as access modifier, name and parameter types of a constructor.
4. java.lang.reflect.Modifier: This class is used to gather information about a particular access modifier.
Purpose of java.lang.Class
The main purpose of java.lang.Class is to gather the complete meta data of a particular class.
How to get complete information about a class
To get information about variables, methods, and constructors of a class, we need to create an object of the class. There are three ways to create objectÂ
1. Using Class.forName()
- It is used to load the class dynamically.
- Returns the instance of Class class.
- It should be used if you know the fully qualified name of class. This cannot be used for primitive types.
Let’s see the simple example of forName() method.
class Employee {}
class Test {
public static void main (String args[]){
Class clazz = Class.forName("com.ashok.reflection.Employee");
}
}
2. Using getClass() method
It returns the instance of Class class. It should be used if you know the type. Moreover, it can be used with primitives.
class Employee {}
class Test {
public static void main (String args[]){
Employee emp = new Employee ();
Class clazz = emp.getClass();
}
}
3. Using the .class syntax
If a 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. It can be used for primitive data type also.
class Employee {}
class Test {
public static void main (String args[]){
Class clazz = Employee.class;
}
}
Example
package com.ashok.reflection;
import java.io.Serializable;
public class Employee implements Serializable, Cloneable {
private static final long serialVersionUID = 1L;
public int empId;
public static String empName;
public String empAddress;
public Employee () {
}
public Employee(int empId, String empName, String empAddress) {
this.empId = empId;
this.empName = empName;
this.empAddress = empAddress;
}
public void addEmployee(int empId, String empName,
String empAddress) {
this.empId = empId;
this.empName = empName;
this.empAddress = empAddress;
}
public void searchEmployee(int empId) {
// search logic to get employee object using empId
}
public int getEmpId() throws Exception {
return empId;
}
public void setEmpId(int empId) {
this.empId = empId;
}
public static String getEmpName() {
return empName;
}
public static void setEmpName(String empName) {
Employee.empName = empName;
}
public String getEmpAddress() {
return empAddress;
}
public void setEmpAddress(String empAddress) {
this.empAddress = empAddress;
}
}
1. Get Metadata of Class
Following example shows how to get metadata such as: Class name, super class name, implemented interfaces, and access modifiers of a class.
package com.ashok.reflection;
import java.lang.reflect.Modifier;
public class ClassMetaData {
public static void main (String [] args) {
Class clazz = Employee.class;
System.out.println("Class Name is: " +clazz.getName());
System.out.println("Super Class Name is: "
+clazz.getSuperclass().getName());
Class [] interfaces = clazz.getInterfaces();
System.out.println("Implemented interfaces are ");
for(Class interf : interfaces) {
System.out.println(interf.getName());
}
System.out.println("Access modifiers are: "
+Modifier.toString(clazz.getModifiers()));
}
}
Output
Class Name is : com.ashok.reflection.Employee
Super Class Name is : java.lang.Object
Implemented interfaces are
java.io.Serializable
java.lang.Cloneable
Access modifiers are: public
2. Get Metadata of Variable
To get the metadata in the form of field array using getFields() or getDeclaredFields() methods Â
1. getFields() method returns metadata of the public variable from the specified class as well as from its super class.
2. getDeclaredFields() method returns metadata of the all the variables from the specified class only.
package com.ashok.reflection;
import java.lang.reflect.Field;
import java.lang.reflect.Modifier;
public class VariableMetaData {
public static void main (String [] args) throws Exception {
Class clazz = Employee.class;
Field [] fields= clazz.getDeclaredFields();
for (Field field: fields) {
System.out.println("Variable name: "+field.getName());
System.out.println("Datatypes of the variable:"
+field.getType());
System.out.println("Access Modifiers of the variable: "
+Modifier.toString(field.getModifiers()));
System.out.println("-------------------------------------");
}
}
}
Output
Variable name: serialVersionUID
Datatypes of the variable:long
Access Modifiers of the variable: private static final
--------------------------------------------------
Variable name: empId
Datatypes of the variable:int
Access Modifiers of the variable: public
--------------------------------------------------
Variable name: empName
Datatypes of the variable:class java.lang.String
Access Modifiers of the variable: public static
--------------------------------------------------
Variable name: empAddress
Datatypes of the variable:class java.lang.String
Access Modifiers of the variable: public
3. Get Metadata of Method
To get the metadata in the form of method array using getMethods() or getDeclaredMethods() methods Â
1. getMethods() method returns metadata of the public methods from the specified class as well as from its super class.
2. getDeclaredMethods() method returns metadata of the all the methods from the specified class only.
package com.ashok.reflection;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
public class MethodMetaData {
public static void main(String[] args) {
Class clazz = Employee.class;
Method[] methods = clazz.getDeclaredMethods();
for (Method method : methods) {
System.out.println("Name of the method: " + method.getName());
System.out.println("Return type of the method: "
+ method.getReturnType());
System.out.println("Method access modifiers: "
+ Modifier.toString(method.getModifiers()));
Class[] paramList = method.getParameterTypes();
for (Class cls : paramList) {
System.out.println(cls.getName() + " ");
}
System.out.println();
Class [] exceptionList = method.getExceptionTypes();
System.out.println("Excpetion thrown by method:");
for (Class cls : exceptionList) {
System.out.println(cls.getName() + " ");
}
System.out.println("---------------------------------");
}
}
}
Output
Name of the method: addEmployee
Return type of the method: void
Method access modifiers: public
Method parameter types:
int
java.lang.String
java.lang.String
Excpetion thrown by method:
---------------------------------------------------
Name of the method: setEmpId
Return type of the method: void
Method access modifiers: public
Method parameter types:
int
Excpetion thrown by method:
---------------------------------------------------
Name of the method: getEmpId
Return type of the method: int
Method access modifiers: public
Method parameter types:
Excpetion thrown by method:
java.lang.Exception
---------------------------------------------------
Name of the method: setEmpAddress
Return type of the method: void
Method access modifiers: public
Method parameter types:
java.lang.String
Excpetion thrown by method:
---------------------------------------------------
Name of the method: setEmpName
Return type of the method: void
Method access modifiers: public static
Method parameter types:
java.lang.String
Excpetion thrown by method:
---------------------------------------------------
Name of the method: getEmpAddress
Return type of the method: class java.lang.String
Method access modifiers: public
Method parameter types:
Excpetion thrown by method:
---------------------------------------------------
Name of the method: getEmpName
Return type of the method: class java.lang.String
Method access modifiers: public static
Method parameter types:
Excpetion thrown by method:
---------------------------------------------------
Name of the method: searchEmployee
Return type of the method: void
Method access modifiers: public
Method parameter types:
int
Excpetion thrown by method:
--------------------------------------------------
4. Get Metadata of Constructors
package com.ashok.reflection;
import java.lang.reflect.Constructor;
import java.lang.reflect.Modifier;
public class ConstructorMetaData {
public static void main(String[] args) {
Class clazz = Employee.class;
Constructor[] constructorList = clazz.getConstructors();
for (Constructor constructor: constructorList) {
System.out.println("Constrcutor name: "+constructor.getName());
System.out.println("Constrctor modifier: "
+Modifier.toString(constructor.getModifiers()));
Class[] paramList=constructor.getParameterTypes();
System.out.println("Constrctor parameter types :");
for (Class class1: paramList) {
System.out.println(class1.getName() +" ");
}
System. out.println();
Class[] exceptionList=constructor.getExceptionTypes();
System.out.println("Exception thrown by constructors:");
for (Class class1: exceptionList) {
System.out.println(class1.getName() +" ");
}
System.out.println("--------------------------------------");
}
}
}
Output
Constrcutor name: com.ashok.reflection.Employee
Constrctor modifier: public
Constrctor parameter types:
Exception thrown by constructors:
------------------------------------------
Constrcutor name: com.ashok.reflection.Employee
Constrctor modifier: public
Constrctor parameter types:
int
java.lang.String
java.lang.String
Exception thrown by constructors:
------------------------------------------
5. Getter and Setter Methods
package com.ashok.reflection;
import java.lang.reflect.Method;
public class GetterAndSetter {
public static void main(String[] args) {
Class clazz = Employee.class;
Method[] methods = clazz.getDeclaredMethods();
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") &&
method.getParameterTypes().length != 0
&& void.class.equals(method.getReturnType()))
return false;
return true;
}
public static boolean isSetter(Method method) {
if (!method.getName().startsWith("set") &&
method.getParameterTypes().length != 1)
return false;
return true;
}
}
Setter: public void com.ashok.reflection.Employee.setEmpId(int)
Setter: public void com.ashok.reflection.Employee.setEmpAddress
(java.lang.String)
Setter: public static void com.ashok.reflection.Employee.setEmpName
(java.lang.String)
Getter: public int com.ashok.reflection.Employee.getEmpId() throws
java.lang.Exception
Getter: public java.lang.String com.ashok.reflection.Employee.
getEmpAddress()
Getter: public static java.lang.String com.ashok.reflection.Employee.
getEmpName()
Invoke methods
package com.ashok.reflection;
public class Employee {
public int empId;
public static String empName;
public String empAddress;
public void addEmployee(int empId, String empName, String empAddress) {
this.empId = empId;
this.empName = empName;
this.empAddress = empAddress;
System.out.println("Inside addEmployee");
}
private void getPrivateData() {
System.out.println("Inside private data");
}
public static void getStaticData() {
System.out.println("Inside Static data");
}
}
package com.ashok.reflection;
import java.lang.reflect.Method;
public class MethodInvoke {
public static void main(String[] args) throws Exception {
Class clazz = Employee.class;
Method method = clazz.getDeclaredMethod("addEmployee",int.class, String.class, String.class);
method.invoke(Employee.class.newInstance(), 87,"Ashok","Bhimavaram");
// Invoke private method
Method privateMethod = clazz.getDeclaredMethod("getPrivateData");
privateMethod.setAccessible(true);
privateMethod.invoke(Employee.class.newInstance());
// Invoke Static method
Method staticMethod = clazz.getDeclaredMethod("getStaticData");
staticMethod.invoke(null);
}
}
Output
Inside addEmployee
Inside private data
Inside Static data
Get annotations at run time using reflection
Annotations allow us to provide metadata (data about data) information into our source code.
package com.ashok.reflection;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
@Retention(RetentionPolicy.RUNTIME)
public @interface MyAnnotation {
public String key();
public String value();
}
package com.ashok.reflection;
import java.lang.reflect.Method;
public class MyAnnotationTest {
@MyAnnotation(key="website", value="https://waytoeasylearn.com")
public void myAnnotationMethod(){
try {
Class cls = this.getClass();
Method method = cls.getMethod("myAnnotationMethod");
MyAnnotation myAnno = method.getAnnotation(MyAnnotation.class);
System.out.println("Key is: "+myAnno.key());
System.out.println("Value is: "+myAnno.value());
} catch (SecurityException e) {
e.printStackTrace();
} catch (NoSuchMethodException e) {
e.printStackTrace();
}
}
public static void main(String a[]){
MyAnnotationTest mat = new MyAnnotationTest();
mat.myAnnotationMethod();
}
}
Key is: website
Value is: https://waytoeasylearn.com
That’s it guys. This is all about Java Reflection Tutorial. Let me know your comments and suggestions about this tutorial. Thank you.