Reflection:
Reflection

1. What is Reflection in Java?

2.Use of Reflection.

3. Where is Reflection API used?

4.Drawbacks of Reflection in Java.

5.Reflection API in Java.

6.Reflection Example code.

What is Reflection in Java.
Reflection API provides the ability to examine and modify the runtime behavior of applications running in the Java virtual machine.
Use of Reflection:

1. In Java, we can inspect a class and get information about the fields, methods, constructors, and implemented interfaces, superclasses at runtime.

2. We can even access the private field and invoke a private method from another class.

Where is Reflection API used?
Reflection API cannot be seen used in the applications but seen its usage in different tools and applications we are using.

1. The Eclipse IDE can be seen using this API where with the use of command or interface we can see the list of methods in a class,auto-completing the fields or method name.

2. The persistence framework matching the fields in the objects with the fields in the database table at runtime.

3. Junits getting information about methods to be invoked.

4. Spring framework getting class information using the bean definition and also for dependency injection using setter and getter or constructor of the class. So here reflection is completely used for dependency injection.

Drawbacks of Reflection in Java:

1. Performance overhead.

2. Security Restrictions

3. Against Object Oriented principles

Reflection API in Java:
Some of the APIs in Java can be used for using Reflection.
1. Class(java.lang.class):
This belongs to java.lang or default package, For any type of object, JVM instantiates an immutable instance of java.lang.Class which provides the method to examine the runtime properties including members and type information of the class. The class also provides the ability to create new classes and
objects. It is the entry point for all reflection API. Class is not part of reflection API it belongs to java.lang package.

2. Member(java.lang.reflect.Member):
This is an interface that belongs to the java.lang.reflect package which is implemented by Field, Method, and Constructor which also belongs to the same package which can be used to get information about class members.
It contains below methods:

-> Class<?> getDeclaringClass();
-> String getName();
-> int getModifiers();

3. Field(java.lang.Reflect.Field):
This class is present in java.lang.Reflect package, It provides methods for accessing type information about setting and getting of values of a field on a given object.
4. Method(java.lang.Reflect.Method):
This class is present in java.lang.Reflect package. It provides information about, and access to, a single method on a class or interface.
5. Constructor(java.lang.Reflect.Constructor) : It provides information about, and access to, a single  constructor for a class.If we invoke constructor it will create a new instance of a class.
6. Array(java.lang.Reflect.Array) :
This class provides static methods to dynamically create and access Java arrays.

 

 

 

Examples Coding to get metadata of the class .

Class: HomeProduct

 

package com.amitclive.model;

@Deprecated
public class HomeProduct extends Product implements ProductInfo{


private int size;

public HomeProduct(String name, Integer price, int size) {
super(name, price);
this.size = size;
}

@Override
public void showSize() {
System.out.println("showSize" +size);

}


}

 

Class:  Product 

package com.amitclive.model;

public class Product {

private String name;
private Integer price;

public Product(String name, Integer price) {
this.name = name;
this.price = price;
}

private Product() {
}

public String getName() {
return name;
}

public void setName(String name) {
this.name = name;
}

public Integer getPrice() {
return price;
}

public void setPrice(Integer price) {
this.price = price;
}

}

Interface: ProductInfo

 

package com.amitclive.model;


public interface ProductInfo {

void showSize();
}


 

Class: ReflectionMetadata

package com.amitclive.client;

import java.lang.annotation.Annotation;
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import java.util.Arrays;

public class ReflectionMetadata {

public static void main(String[] args) {

// To get the classname

try {
Class<?> c1 = Class.forName("com.amitclive.model.HomeProduct");

System.out.println("classname : " + c1.getName());
System.out.println("classname : " + c1.getSimpleName());

} catch (ClassNotFoundException e) {
e.printStackTrace();
}

// To get the superclass
try {
Class<?> c1 = Class.forName("com.amitclive.model.HomeProduct");

System.out.println("super classname : " + c1.getSuperclass());

} catch (ClassNotFoundException e) {
e.printStackTrace();
}

// Getting implemented and extended interfaces using reflection
try {
Class<?> c1 = Class.forName("com.amitclive.model.HomeProduct");

System.out.println("interfaces : " + Arrays.toString(c1.getInterfaces()));

} catch (ClassNotFoundException e) {
e.printStackTrace();
}

// Getting class modifier using reflection
try {
Class<?> c1 = Class.forName("com.amitclive.model.HomeProduct");
int modifiers = c1.getModifiers();
System.out.println("Modifers : " + Modifier.toString(modifiers));

} catch (ClassNotFoundException e) {
e.printStackTrace();
}

// Get fields of the class
try {
Class<?> c1 = Class.forName("com.amitclive.model.HomeProduct");
Field[] field = c1.getFields();
System.out.println("Fields : " + Arrays.toString(field));

Field[] fieldDeclared = c1.getDeclaredFields();
System.out.println("Fields : " + Arrays.toString(fieldDeclared));

} catch (ClassNotFoundException e) {
e.printStackTrace();
}

// Get constructors of the class
try {
Class<?> c1 = Class.forName("com.amitclive.model.HomeProduct");
Constructor[] construct = c1.getConstructors();
System.out.println("Constructor : " + Arrays.toString(construct));

Constructor[] constructDecalred = c1.getDeclaredConstructors();
System.out.println("Constructor : " + Arrays.toString(constructDecalred));

} catch (ClassNotFoundException e) {
e.printStackTrace();
}

// Get Methods of the class using reflection
try {
Class<?> c1 = Class.forName("com.amitclive.model.HomeProduct");
Method[] method = c1.getMethods();
System.out.println("Method : " + Arrays.toString(method));

Method[] methodDecalred = c1.getDeclaredMethods();
System.out.println("Method : " + Arrays.toString(methodDecalred));

} catch (ClassNotFoundException e) {
e.printStackTrace();
}

// Get Annotations of the class using reflection
try {
Class<?> c1 = Class.forName("com.amitclive.model.HomeProduct");
Annotation[] annotations = c1.getAnnotations();
System.out.println("Annotation : " + Arrays.toString(annotations));

Annotation[] annotationsDeclared = c1.getDeclaredAnnotations();
System.out.println("Annotation : " + Arrays.toString(annotationsDeclared));

} catch (ClassNotFoundException e) {
e.printStackTrace();
}

}

}

 

Examples Coding to get Constructor, methods , fields .

Class:  Product

package com.amitclive.model;

public class Product {

private String name;
private Integer price;

public Product(String name, Integer price) {
this.name = name;
this.price = price;
}

private Product() {
}

public String getName() {
return name;
}

public void setName(String name) {
this.name = name;
}

public Integer getPrice() {
return price;
}

public void setPrice(Integer price) {
this.price = price;
}

}

Class: ReflectionTest

 

package com.amitclive.client;

import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.util.Arrays;

public class ReflectionTest {

public static void main(String[] args) throws ClassNotFoundException, NoSuchMethodException, SecurityException {

Class<?> cls = Class.forName("com.amitclive.model.Product");

// Get Constructor of the class
Constructor<?>[] construct = cls.getConstructors();
System.out.println("Get Constructor of the class =====");
System.out.println("" + Arrays.toString(construct));
// Get declared methods of the class

Method[] declaredMethod = cls.getDeclaredMethods();
System.out.println("Get declared methods of the class =====");
System.out.println("" + Arrays.toString(declaredMethod));

// Get all methods including inherited of the class
Method[] methods = cls.getMethods();
System.out.println("Get all methods including inherited of the class =====");
System.out.println("" + Arrays.toString(methods));

// Get fields of the class
Field[] fields = cls.getDeclaredFields();
System.out.println("Get fields of the class =====");
System.out.println("" + Arrays.toString(fields));
}

}




Examples Coding to access private  member, fields.

Class: Welcome

package com.amitclive.model;

public class Welcome {

private String message ="Welcome Back";

}

Class: ReflectionPrivateAccess

package com.amitclive.client;

import java.lang.reflect.Field;

import com.amitclive.model.Welcome;

public class ReflectionPrivateAccess {

public static void main(String[] args) {

try {
Class<?> cls = Class.forName("com.amitclive.model.Welcome");
Field field = cls.getDeclaredField("message");
field.setAccessible(true);
Object object = field.get(new Welcome());
String result = (String) object;
System.out.println(result);
} catch (ClassNotFoundException | NoSuchFieldException | SecurityException | IllegalArgumentException
| IllegalAccessException e) {
e.printStackTrace();
}
}

}

 

 

Creating class instance using reflection:
In reflection API, there are two methods for creating instances of class:
java.lang.reflect.Constructor.newInstanace() and Class.newInstance().
It is preferable to go with the one provided by the Constructor class for the reasons explained here.
-> Class.newInstance() can only invoke the zero-argument constructor, while Constructor.newInstace() may invoke any constructor,
regardless the number of parameters.
-> Class.newInstance() requires the constructor be visible; Constructor.newInstance() can invoke private constructor also by setting accessibility
true.
->Class.newInstance() throws any exception thrown by the constructor whether it is checked or unchecked exception. Constructor.newInstance()
always wraps the thrown exception with an InvocationTargetException.

Examples Coding to determine if the class member is of an array type.

Class: Student

 

package com.amitclive.model;

public class Student {

private int name;
private long[] phoneNumbers;
public Student(int name, long[] phoneNumbers) {
super();
this.name = name;
this.phoneNumbers = phoneNumbers;
}
public int getName() {
return name;
}
public void setName(int name) {
this.name = name;
}
public long[] getPhoneNumbers() {
return phoneNumbers;
}
public void setPhoneNumbers(long[] phoneNumbers) {
this.phoneNumbers = phoneNumbers;
}


}

Class: IdentifyArray

package com.amitclive.client;

import java.lang.reflect.Field;

//To determine if the class member is of an array type
public class IdentifyArray {

public static void main(String[] args) {

try {
Class<?> cls = Class.forName("com.amitclive.model.Student");
Field[] field = cls.getDeclaredFields();
for (Field f : field) {
Class<?> type = f.getType();

if (type.isArray()) {
System.out.println("Array Found : " + f.getName());
}
}
} catch (ClassNotFoundException e) {
e.printStackTrace();
}

}

}

 

 

Examples Coding for Creating class instance using reflection.

Class: Product

package com.amitclive.model;

public class Product {

private String name;
private Integer price;

public Product(String name, Integer price) {
this.name = name;
this.price = price;
}

private Product() {
}

public String getName() {
return name;
}

public void setName(String name) {
this.name = name;
}

public Integer getPrice() {
return price;
}

public void setPrice(Integer price) {
this.price = price;
}

}

 

Class:  InstanceCreation 

package com.amitclive.client;

import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Modifier;

import com.amitclive.model.Product;

public class InstanceCreation {

	public static void main(String[] args) {

		try {
			Class<?> cls = Class.forName("com.amitclive.model.Product");

			Constructor<?>[] constructor = cls.getConstructors();
			for (Constructor con : constructor) {
				System.out.println(con.getName());

				Product prod;
				if (Modifier.toString(con.getModifiers()).equals("private")) {
					// set accessibility to true if its a private constructor
					con.setAccessible(true);
					prod = (Product) con.newInstance();
				} else {
					prod = (Product) con.newInstance("consructortest", 200);
				}
				System.out.println(prod.getPrice());
			}
		} catch (ClassNotFoundException | InstantiationException | IllegalAccessException | IllegalArgumentException
				| InvocationTargetException e) {
			e.printStackTrace();
		}
	}

}

Amit is a software developer by profession. He is passionate about all the technologies which can be used to build an application like java related technologies and many more and loves to implement it his career or for knowledge purpose and share his experience with you all. To know more see the About me profile.

Leave a Reply

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

This site uses Akismet to reduce spam. Learn how your comment data is processed.