Reflections in Java
Reflections in Java
-----------------------------------------
Ability of computer program to examine, introspect its own behaviour at runtime
applications running in java virtual machine.
-----------------------------------------
Use of Reflection
-----------------------------------------
Using Reflection in Java we can inspect a class and get information about the
fields, methods, constructors, implemented interfaces, superclasses at run time.
Using reflection, we can access a private field and invoke a private method from
another class.
-----------------------------------------
Where is reflection API used
-----------------------------------------
You may not have a need to use reflection API in your application but you would
have seen its usage in many tools or applications you are using.
1. The IDE like Eclipse giving you the list of methods in a class, auto completing
the field or method name.
2. Your persistance framework matching the fields in your objects with fields in
the database table at runtime.
3. JUnit getting the information about the methods to be invoked.
4. Spring framework getting the class information using the bean definition and
also getting the setters and gertters or constructors of the class. So, you can say
Dependency Injection in Spring depends heavily on reflection.
-----------------------------------------
Drawbacks of reflection in java
-----------------------------------------
Performance Overhead(Since it should have access to runtime)
Security Restrictions
Against Object oriented principles(Breaks abstraction)
-----------------------------------------
Reflection API in java
-----------------------------------------
-> Class(java.lang.Class)
For every type of object, JVM instantiates an immutable instance of java which
provides methods to examine the runtime properties of object including its members
and type information. Class also provides a new ability to create objects, most
importantly it is the entry point for all the reflection API.
->Member(java.lang.reflect.Member)
This is an interface.
-Field(java.lang.reflect.Field)
Field class provides methods for type information for setting and getting fields
for the given object.
->Method(java.lang.reflect.Method)
Method class provides methods for obtaining type information for the parameters and
return types. It may also be used to invoke methods on the given object.
->Constructor(java.lang.reflect.Constructor)
Constructor class provides methods for obtaining the information about constructor
of the class. If we reflectively invoke the constructor, a new instance of the
given class will be created.
->Array(java.lang.reflect.Array)
The array class provides static methods to create dynamically and access java
arrays.
-----------------------------------------
Reflection Example code
-----------------------------------------
Person.class
package com.infotech.model;
Test.class
package com.infotech.client;
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.util.Arrays;
try {
Class<?> c = Class.forName("com.infotech.model.Person");
} catch(ClassNotFoundException e) {
e.printStackTrace();
}
}
-----------------------------------------
Getting the metadata about the class using Reflection API
-----------------------------------------
IntTest.class
package com.infotech.model;
Parent.class
package com.infotech.model;
}
ChildClass.class
package com.infotech.model;
//@Deprecated
public class ChildClass extends Parent implements IntTest {
@Override
public void showValue() {
System.out.println("Value:" +value);
}
ReflectionTest.class
package com.infotech.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;
try {
c1 = Class.forName("com.infotech.model.ChildClass");
System.out.println("Class name : " + c1.getName());
System.out.println("Class name : " + c1.getSimpleName());
}catch(ClassNotFoundException e) {
e.printStackTrace();
}
try {
c2 = Class.forName("com.infotech.model.ChildClass");
System.out.println("Super Class name : " + c2.getSuperclass());
}catch(ClassNotFoundException e) {
e.printStackTrace();
}
System.out.println("-------------------------------3. Getting
implemented or extended interfaces using reflection----------------------");
Class<?> c3;
try {
c3 = Class.forName("com.infotech.model.ChildClass");
System.out.println("Interface : " +
Arrays.toString(c3.getInterfaces()));
}catch(ClassNotFoundException e) {
e.printStackTrace();
}
System.out.println("-------------------------------4.
Getting class modifiers using reflection----------------------");
Class<?> c4;
try {
c4 = Class.forName("com.infotech.model.ChildClass");
int modifiers = c4.getModifiers();
System.out.println("Modifiers : " +
Modifier.toString(modifiers));
}catch(ClassNotFoundException e) {
e.printStackTrace();
}
System.out.println("-------------------------------5.
Getting fields of the class using reflection----------------------");
Class<?> c5;
try {
c5 = Class.forName("com.infotech.model.ChildClass");
//getting fields of the class
Field[] fields = c5.getFields();
System.out.println("All accessible Fields(public) : "
+ Arrays.toString(fields));
}catch(ClassNotFoundException e) {
e.printStackTrace();
}
try {
c6 = Class.forName("com.infotech.model.ChildClass");
//getting fields of the class
Constructor<?>[] constructors = c6.getConstructors();
System.out.println("All accessible
constructors(public) : " + Arrays.toString(constructors));
}catch(ClassNotFoundException e) {
e.printStackTrace();
}
System.out.println("-------------------------------7.
Getting methods of the class using reflection----------------------");
Class<?> c7;
try {
c7 = Class.forName("com.infotech.model.ChildClass");
//getting fields of the class
Method[] methods = c7.getMethods();
System.out.println("All accessible methods including
parent : " + Arrays.toString(methods));
}catch(ClassNotFoundException e) {
e.printStackTrace();
}
System.out.println("------------------------------8.
Getting annotations of the class using reflection----------------------");
Class<?> c8;
try {
c8 = Class.forName("com.infotech.model.ChildClass");
//getting fields of the class
Annotation[] annotations = c8.getAnnotations();
System.out.println("All accessible annotations
including parent : " + Arrays.toString(annotations));
}catch(ClassNotFoundException e) {
e.printStackTrace();
}
}
-----------------------------------------
Invoking private method of the class from another class using reflection in java
-----------------------------------------
Welcome.class
package com.infotech.model;
}
}
ReflectionTest.class
package com.infotech.client;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import com.infotech.model.Welcome;
try {
Class<?> cls = Class.forName("com.infotech.model.Welcome");
Method method = cls.getDeclaredMethod("greet", String.class);
method.setAccessible(true);
}
-----------------------------------------
Access private variables from another class in java
-----------------------------------------
Welcome.class
package com.infotech.model;
ReflectionTest.class
package com.infotech.client;
import java.lang.reflect.Field;
import com.infotech.model.Welcome;
-----------------------------------------
Creating class instance using reflection
-----------------------------------------
Using Constructor clas in java, we can get information about the modifiers,
parameters, annotations and thrown exceptions. You can also create a new instance
of a class using a specified constructor.
getConstructor(Class<?>... parameterTypes)
getConstructors()
getDeclaredConstructor(Class<?>... parameterTypes)
getDeclaredConstructors()
TestClass.class
package com.infotech.model;
ReflectConstructorTest.class
package com.infotech.client;
import java.lang.reflect.Constructor;
import java.util.Arrays;
try {
Class<?> cls = Class.forName("com.infotech.model.TestClass");
TestClass.class
package com.infotech.model;
// private constructor
private TestClass() {
ReflectionTest.class
package com.infotech.Client;
import java.lang.reflect.Constructor;
import java.lang.reflect.Modifier;
import com.infotech.model.TestClass;
try {
cls = Class.forName("com.infotech.model.TestClass");
Constructor<?>[] cons = cls.getDeclaredConstructors();
for (Constructor<?> con : cons) {
System.out.println("Constructor :" + con.getName());
try {
TestClass testClass;
if(Modifier.toString(con.getModifiers()).equals("private")) {
//Setting accessibility as true
con.setAccessible(true);
testClass = (TestClass)con.newInstance();
} else {
testClass = (TestClass) con.newInstance(200,
"ConstructorTest");
}
testClass.showValue();
}catch (Exception e) {
}
}
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
-----------------------------------------
Identify array using reflection and creating new array using reflection
-----------------------------------------
Person.class
package com.infotech.model;
IdentifyArrayUsingReflectionTest.class
package com.infotech.client;
import java.lang.reflect.Field;
public class IdentifyArrayUsingReflectionTest {
try {
Class<?> cls = Class.forName("com.infotech.model.Person");
Field[] fields = cls.getDeclaredFields();
for (Field f : fields) {
Class<?> type = f.getType();
GetAndSetArrayUsingReflectionTest.class
package com.infotech.client;
import java.lang.reflect.Array;
-----------------------------------------
Generating Getter and Setters method in java
-----------------------------------------