Java Reflection

Java Reflection

“Reflection is commonly used by programs which require the ability to examine or modify the runtime behavior of applications running in Java Virtual machine.” The concept is ofen mixed with introspecion.The following are their definitions from Wiki:

what is Introspection and reflection?

  1. Introspection is the ability of a program to examine the type or properties of an object at runtime.
  2. Relection is the ability of a program to examine and modify the structure and behavior of an object at runtime.

Why do we need reflection?

  1. Examine an object’s class at runtime
  2. Construct an object for a class at runtime
  3. Examine a class’s field adn method at runtime
  4. Invoke any method of an object at runtime
  5. Change accessibility flag of Constructor, Method,Field
  6. etc.

For example, JUnit use reflection to look through methods tagged with the @Test annotation, and then call those methods when running the unit test. (Here is a set of examples of how to use JUnit.)

For web frameworks, product developers define their own implementation of interfaces and classes and put is in the configuration files. Using reflection,it can quickly dynamically initialize the classes required.

For example ,Spring uses bean configuration such as

1
2
3
<bean id="someID" class="com.Foo">
<property name="someField" value="someValue"/>
</bean>

When the Spring context processes this element,it will use Class.forName(String) with the arguement”com.Foo” to instantiate the Class.It will then again use Reflection to get the appropriate setter for the element and set its value to the sepcified value.

The same mechanism is also used for Servlet web application

1
2
3
4
<Servlet>
<Servlet-name>someServlet</Servlet-name>
<Servlet-class>com.Foo</Servlet-class>
<Servlet>

how to use reflection?

Example 1: Get Class name from object

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
package myreflection;
import java.lang.reflect.Method;

public class ReflectionHelloWorld {
public static void main(String[] args){
Foo f = new Foo();
System.out.println(f.getClass().getName());
}
}

class Foo {
public void print() {
System.out.println("abc");
}
}

Output:

1
myreflection.Foo

Example 2:Invoke method on unknown object

For the code example blow ,image the types of an object is unknown.By using reflection,the code can use the object and find out if the object has a method called “print” and the call it.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
package myreflection;
import java.lang.reflect.Method;

public class ReflectionHelloWorld {
public static void main(String[] args){
Foo f = new Foo();

Method method;
try {
method = f.getClass().getMethod("print", new Class<?>[0]);
method.invoke(f);
} catch (Exception e) {
e.printStackTrace();
}
}
}

class Foo {
public void print() {
System.out.println("abc");
}
}

Example 3: Create object from Class instance

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
package myreflection;

public class ReflectionHelloWorld {
public static void main(String[] args){
//create instance of "Class"
Class<?> c = null;
try{
c=Class.forName("myreflection.Foo");
}catch(Exception e){
e.printStackTrace();
}

//create instance of "Foo"
Foo f = null;

try {
f = (Foo) c.newInstance();
} catch (Exception e) {
e.printStackTrace();
}

f.print();
}
}

class Foo {
public void print() {
System.out.println("abc");
}
}

Example 4: Get constructor and create instance

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
package myreflection;

import java.lang.reflect.Constructor;

public class ReflectionHelloWorld {
public static void main(String[] args){
//create instance of "Class"
Class<?> c = null;
try{
c=Class.forName("myreflection.Foo");
}catch(Exception e){
e.printStackTrace();
}

//create instance of "Foo"
Foo f1 = null;
Foo f2 = null;

//get all constructors
Constructor<?> cons[] = c.getConstructors();

try {
f1 = (Foo) cons[0].newInstance();
f2 = (Foo) cons[1].newInstance("abc");
} catch (Exception e) {
e.printStackTrace();
}

f1.print();
f2.print();
}
}

class Foo {
String s;

public Foo(){}

public Foo(String s){
this.s=s;
}

public void print() {
System.out.println(s);
}
}

Output:

1
2
null
abc

Example 5: Change array size though reflection

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
package myreflection;

import java.lang.reflect.Array;

public class ReflectionHelloWorld {
public static void main(String[] args) {
int[] intArray = { 1, 2, 3, 4, 5 };
int[] newIntArray = (int[]) changeArraySize(intArray, 10);
print(newIntArray);

String[] atr = { "a", "b", "c", "d", "e" };
String[] str1 = (String[]) changeArraySize(atr, 10);
print(str1);
}

// change array size
public static Object changeArraySize(Object obj, int len) {
Class<?> arr = obj.getClass().getComponentType();
Object newArray = Array.newInstance(arr, len);

//do array copy
int co = Array.getLength(obj);
System.arraycopy(obj, 0, newArray, 0, co);
return newArray;
}

// print
public static void print(Object obj) {
Class<?> c = obj.getClass();
if (!c.isArray()) {
return;
}

System.out.println("\nArray length: " + Array.getLength(obj));

for (int i = 0; i < Array.getLength(obj); i++) {
System.out.print(Array.get(obj, i) + " ");
}
}
}

Output:

1
2
3
4
Array length: 10
1 2 3 4 5 0 0 0 0 0
Array length: 10
a b c d e null null null null null

Reference

You may Also Like