Overview

In this blog, we will cover the following points

  • What is Reflection API?
  • Using private methods
  • Using private fields
  • Sample Code

Reflection API

  • Reflection allows instantiation of new objects, invocation of methods, and get/set operations on class variables dynamically at run time without having prior knowledge of its implementation.
Real-World Example:
  • Take for example your typical web.xml file.
  • This will contain a list of servlet elements, which contain nested servlet-class elements.
  • The servlet container will process the web.xml file, and create new a new instance of each servlet class through reflection.
  • Another example would be the Java API for XML Parsing (JAXP).
  • Where an XML parser provider is ‘plugged-in’ via well-known system properties, which are used to construct new instances through reflection.
  • The most comprehensive example is Spring which uses reflection to create its beans, and for its heavy use of proxies
<bean id="someID" class="com.example.Foo">
<property name="someField" value="someValue" />
</bean>
  • When the Spring context processes this < bean > element, it will use Class.forName(String) with the argument com.example.Foo to instantiate that class.
  • It will then again use reflection to get the appropriate setter for the < property > element and set its value to the specified value.
  • JUnit uses Reflection especially for testing Private/Protected methods.
Reflection for private methods
Method method = targetClass.getDeclaredMethod(methodName, argClasses);
method.setAccessible(true); // Change method scope from private to public
return method.invoke(targetObject, argObjects);
Reflection for private fields
Field field = targetClass.getDeclaredField(fieldName);
field.setAccessible(true); // Change field scope from private to public
field.set(object, value);
Advantage:
  • Reflection is also more powerful, you can retrieve the definition of a protected or final member, remove the protection and manipulate it as if it had been declared mutable!
Disadvantage
  • Reflection is much slower than just calling methods by their name because it has to inspect the metadata in the bytecode instead of just using precompiled addresses and constants.
Program:
  • In the following example, we will see how we can use Reflection to get class info like constructor, methods. fields etc.
import static java.lang.System.out;

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

class DemoReflection {
private String test1 = "Hello";
static {
System.out.println("Static Block Called");
}

public String readData() {
return test1;
}

private String readPrivateData() {
return test1;
}
}

public class ReflectionMain {

public static void main(String... args1) {
try {
Class<?> c = Class.forName("com.main.reflection.DemoReflection");
out.format("Class:%n %s%n%n", c.getCanonicalName());
Package p = c.getPackage();
out.format("Package:%n %s%n%n", (p != null ? p.getName()
: "-- No Package --"));

// Get nConstructors
Constructor[] cons = c.getConstructors();
out.format("%nConstructors:%n %n");
for (int i = 0; i < cons.length; i++) {
out.println(cons[i].getName());
}

// Get Fields
Field[] fields = c.getFields();
out.format("%nFields:%n %n");
for (int i = 0; i < fields.length; i++) {
out.println(fields[i].getName());
}

// Get methods
Method[] methods = c.getMethods();
out.format("%nMethods:%n %n");
for (int i = 0; i < methods.length; i++) {
System.out.println(methods[i].getName());
}

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



OUTPUT:



Static Block Called
Class:
com.main.reflection.DemoReflection

Package:
com.main.reflection


Constructors:


Fields:


Methods:

readData
wait
wait
wait
equals
toString
hashCode
getClass
notify
notifyAll

 

Categories: JAVA

0 Comments

Leave a Reply

Avatar placeholder

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