What is reflection, why is it useful, and how to use it?
1. What is reflection?
"Reflection is typically a capability that a program running in the JVM needs to detect and modify the behavior of the runtime program. This concept is often confused with introspection (introspection). Here are the definitions of the two terms in Wikipedia:
- Introspection refers to the ability of a computer program to check object types at run time, often referred to as run-time type checking.
- Reflection refers to the ability of a computer program to access, detect, and modify its own state or behavior at run time.
As can be seen from their definition, introspection is a subset of reflection. Some languages support introspection, but reflection is not supported, such as C + +.
Introspection Example: The instanceof operator is used to determine whether an object belongs to a particular class.
if (obj instanceof Dog) {
Dog d = (dog) obj;
D.bark ();
}
Reflection Example: the Class.forName () method returns an object of the corresponding class through the name of a class or interface (a string and a fully qualified name). The Forname method initializes the class.
With Reflection
class<?> C = class.forname ("Classpath.and.classname");
Object dog = C.newinstance ();
Method m = c.getdeclaredmethod ("Bark", new class<?>[0]);
M.invoke (dog);
In Java, focus more on reflection than introspection, because you can't change the structure of an object.
2. Why do we need reflection?
Reflection allows us to:
- The runtime detects the class to which an object belongs;
- The runtime constructs an object of a class;
- The runtime detects the fields and methods of a class;
- Any method of invoking an object at run time;
- Modify the access rights of constructors, methods, fields, AccessibleObject setaccessible (Boolean flag) method;
- Wait a minute
Reflection is a common method in a frame.
For example, JUnit looks for methods marked as @Test annotations by reflection and calls them when the unit test is run.
For web frameworks, product developers define the implementation of interfaces and classes in a configuration file. By using reflection, the framework can quickly and dynamically initialize the required classes.
For example, the spring framework uses the bean's configuration, such as:
<bean id= "Someid" class= "Com.programcreek.Foo" >
<property name= "Somefield" value= "somevalue"/>
</bean>
When the spring context handles the <bean> element, the class is instantiated using Class.forName (String) and the parameter "Com.programcreek.Foo". It then uses reflection again to get the setter method corresponding to the <property> element and set the specified value.
The same mechanism is also used for servlet Web applications:
<servlet>
<servlet-name>someServlet</servlet-name>
<servlet-class>com.programcreek.WhyReflectionServlet</servlet-class>
<servlet>3. How do I use reflection?
Learn how to use reflection by following a few typical small examples.
Example 1: Gets the class name of the object.
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:
Myreflection. Foo
Example 2: Calling a method of an unknown object.
For the following code example, it is an illusion that the type of the object is unknown. By using reflection, the code can use the object and find out that the object has a method called "print" and then call it.
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");
}
}abc
Example 3: Creating an object from a class instance
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 the constructor and create an instance.
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);
}
}null
Abc
In addition, you can use a class instance to get the interface that the class implements, the parent class, the declared field, and so on.
Example 5: Modifying the size of an array by reflection.
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:
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 summary
The above code example shows only a very small subset of the functionality that Java reflection provides. Reading these examples only gives you a first-glance view of Java reflection, and you need to read the documentation on Oracle's website for more information.
Java Reflection Tutorial