Java Reflection (JAVA reflection) Detailed

Reflection is one of the characteristics of the development of the Java programming language, which allows a Java program running on their own inspection, or "self-examination" and can attribute directly to the internal operating procedures. For example, use it to get the name of the Java class members and displayed.

Java might use this capability was not much in practical applications, but this feature does not exist in other programming languages. For example, Pascal, C or C ++, there is no way to get information related to the function definition in the program.

  JavaBean is a reflection of one practical application, it allows visualization of some of the tools operating software components. These tools are loaded dynamically through reflection and acquired properties Java components (classes) of.

1. A simple example

  Consider the following simple example, let's see how reflection works.

import java.lang.reflect.*;
public class DumpMethods {
public static void main(String args[]) {
try {
Class c = Class.forName(args[0]);
Method m[] = c.getDeclaredMethods();
for (int i = 0; i < m.length; i++)
System.out.println(m[i].toString());
} catch (Throwable e) {
System.err.println(e);
}
}
}


  Execute the following statement:

java DumpMethods java.util.Stack


  Its output is the result of:

public java.lang.Object java.util.Stack.push(java.lang.Object)

public synchronized java.lang.Object java.util.Stack.pop()

public synchronized java.lang.Object java.util.Stack.peek()

public boolean java.util.Stack.empty()

public synchronized int java.util.Stack.search(java.lang.Object)


  This lists the java.util.Stack class method names and their qualifier and return type.

  This program uses Class.forName load the specified class, then call getDeclaredMethods to get this class defines a list of methods. java.lang.reflect.Methods class is a class used to describe a single method.


2. Reflection started

  for the reflection type, such as Method, you can be found in java.lang.relfect package. When using these classes must follow three steps: The first step is to obtain java.lang.Class object class you want to operate. In the running Java program with java.lang.Class class to describe classes and interfaces.

Here is one way to get a Class object:

Class c = Class.forName("java.lang.String");


  This statement to get a String class class object. There is another method, such as the following statement:

Class c = int.class;


  or

Class c = Integer.TYPE;


  Class information available to them basic types. A method wherein the access is in the TYPE field basic types of packages (such as Integer) are predefined.

  The second step is to call a method such as getDeclaredMethods in order to obtain a list of all the methods defined in the class.

  Once this information is acquired, the third step can be carried out - using the reflection API to manipulate information, such as the following code:

Class c = Class.forName("java.lang.String");

Method m[] = c.getDeclaredMethods();

System.out.println(m[0].toString());


  It prints the first prototype of a String method defined in text.

  In the following example, the three step process for using reflection to exemplify particular applications.

Analog instanceof operator

  after obtaining such information, the next step is usually to resolve some fundamental questions about the Class objects. For example, Class.isInstance method may be used to simulate instanceof operator:

class A {
}

public class instance1 {
public static void main(String args[]) {
try {
Class cls = Class.forName("A");
boolean b1 = cls.isInstance(new Integer(37));
System.out.println(b1);
boolean b2 = cls.isInstance(new A());
System.out.println(b2);
} catch (Throwable e) {
System.err.println(e);
}
}
}


  Class object creates a class A in this example, and then check whether some of the objects are examples of A. Integer (37) is not, but the new A () Yes.


3. Find the class method

  to find a class defines what methods, it is also a very valuable use of very basic reflection. The following code to achieve this usage:

import java.lang.reflect.*;

public class method1 {
private int f1(Object p, int x) throws NullPointerException {
if (p == null)
throw new NullPointerException();
return x;
}

public static void main(String args[]) {
try {
Class cls = Class.forName("method1");
Method methlist[] = cls.getDeclaredMethods();
for (int i = 0; i < methlist.length; i++) {
Method m = methlist[i];
System.out.println("name = " + m.getName());
System.out.println("decl class = " + m.getDeclaringClass());
Class pvec[] = m.getParameterTypes();
for (int j = 0; j < pvec.length; j++)
System.out.println("param #" + j + " " + pvec[j]);
EVEC class [] = m.getExceptionTypes ();
for (int J = 0; J <evec.length; J ++)
System.out.println ( "EXC #" + J + "" + EVEC [J]);
the System. Out.println ( "return type =" + m.getReturnType ());
System.out.println ( "-----");
}
} the catch (the Throwable E) {
System.err.println (E);
}
}
}
  this program first obtains described method1 class then calls method getDeclaredMethods to obtain a series of objects, which describe a method in the class definition of each, including public methods, protected methods, and methods Package private methods. If you use getMethods in the program instead of getDeclaredMethods, you can inherit various ways to get the information.

 After obtaining the Method list of objects to be displayed parameter types of these methods, exception types and return value types not difficult. These types are the basic type or class type description can be given by the object class in order.

  Output results are as follows:

name = f1

decl class = class method1

param #0 class java.lang.Object

param #1 int

exc #0 class java.lang.NullPointerException

return type = int

-----
name = main

decl class = class method1

param #0 class [Ljava.lang.String;

return type = void



4. Get configuration information

  acquired in the class constructor method for acquiring usage and usage similar to the above, such as:

import java.lang.reflect.*;

public class constructor1 {
public constructor1() {
}

protected constructor1(int i, double d) {
}

public static void main(String args[]) {
try {
Class cls = Class.forName("constructor1");
Constructor ctorlist[] = cls.getDeclaredConstructors();
for (int i = 0; i < ctorlist.length; i++) {
Constructor ct = ctorlist[i];
System.out.println("name = " + ct.getName());
System.out.println("decl class = " + ct.getDeclaringClass());
Class pvec[] = ct.getParameterTypes();
for (int j = 0; j < pvec.length; j++)
System.out.println("param #" + j + " " + pvec[j]);
Class evec[] = ct.getExceptionTypes();
for (int j = 0; j < evec.length; j++)
System.out.println("exc #" + j + " " + evec[j]);
System.out.println("-----");
}
} catch (Throwable e) {
System.err.println(e);
}
}
}


  This case did not get the return type of information, it is because the constructor does not return type.

  The result is that the program is running:

name = constructor1

decl class = class constructor1

-----
name = constructor1

decl class = class constructor1

param #0 int

param #1 double



5. Get Class field (field)

to identify a class defines which data fields are also possible, following this code in the dry matter:

import java.lang.reflect.*;

public class field1 {
private double d;
public static final int i = 37;
String s = "testing";

public static void main(String args[]) {
try {
Class cls = Class.forName("field1");
Field fieldlist[] = cls.getDeclaredFields();
for (int i = 0; i < fieldlist.length; i++) {
Field fld = fieldlist[i];
System.out.println("name = " + fld.getName());
System.out.println("decl class = " + fld.getDeclaringClass());
System.out.println("type = " + fld.getType());
int mod = fld.getModifiers();
System.out.println("modifiers = " + Modifier.toString(mod));
System.out.println("-----");
}
} catch (Throwable e) {
System.err.println(e);
}
}
}


  This example is very similar to the previous example. Example Modifier uses a new thing, it is a reflection type, used to describe the field member modifier, such as "private int". These modifiers are described by integers themselves, and the use to return the string Modifier.toString described in the "official" order (e.g., "static" prior to "final"). The output of this program are:

name = d

decl class = class field1

type = double

modifiers = private

-----
name = i

decl class = class field1

type = int

modifiers = public static final

-----
name = s

decl class = class field1

type = class java.lang.String

modifiers =


  And about the situation of the acquisition method, when you can get the field has made only affirmed in the current class field information (getDeclaredFields), or you can get the field (getFields) defined in the parent class.


6. The method of performing the method according to the name of

  the text here, the example given, without exception, and how to obtain the information about the class. We can also use reflection to do some other things, such as the implementation of a method name is specified. The following example illustrates this operation:

import java.lang.reflect.*;
public class method2 {
public int add(int a, int b) {
return a + b;
}
public static void main(String args[]) {
try {
Class cls = Class.forName("method2");
Class partypes[] = new Class[2];
partypes[0] = Integer.TYPE;
partypes[1] = Integer.TYPE;
Method meth = cls.getMethod("add", partypes);
method2 methobj = new method2();
Object arglist[] = new Object[2];
arglist[0] = new Integer(37);
arglist[1] = new Integer(47);
Object retobj = meth.invoke(methobj, arglist);
Integer retval = (Integer) retobj;
System.out.println(retval.intValue());
} catch (Throwable e) {
System.err.println(e);
}
}
}


If a program somewhere in the implementation of the time required to execute a method to know the name of this method is specified in the process of running the program (for example, JavaBean development environment would do such a thing), then the above procedure It demonstrates how to do it.

  In the embodiment, getMethod a method for finding two integer parameters and having called add. After finding the method and create the corresponding Method object, execute it in the correct object instance. When performing the method, it is necessary to provide a list of parameters, which in the embodiment is packaged, Integer two objects 37 and 47 of integers. Returning execution of the method is also an Integer object that encapsulates the return value 84.


7. Create a new object

  for the constructor, it can not be like that execution method, because it means that the implementation of a constructor creates a new object (to be exact, to create an object of the process including the allocation of memory and construct an object). Therefore, with the embodiment most similar to the following example:

import java.lang.reflect.*;

public class constructor2 {
public constructor2() {
}

public constructor2(int a, int b) {
System.out.println("a = " + a + " b = " + b);
}

public static void main(String args[]) {
try {
Class cls = Class.forName("constructor2");
Class partypes[] = new Class[2];
partypes[0] = Integer.TYPE;
partypes[1] = Integer.TYPE;
Constructor ct = cls.getConstructor(partypes);
Object arglist[] = new Object[2];
arglist[0] = new Integer(37);
arglist[1] = new Integer(47);
Object retobj = ct.newInstance(arglist);
} catch (Throwable e) {
System.err.println(e);
}
}
}


  Find the corresponding constructor types based on specified parameters and execute it, to create a new object instance. You can be dynamically created using this method at runtime objects, rather than create objects at compile time, which is very valuable.


8. Change field (field) value

  reflection Another use is to change the value of the target data field. reflection can be found running programs in the field based on the name of the object and change it, the following examples illustrate this point:

import java.lang.reflect.*;

public class field2 {
public double d;

public static void main(String args[]) {
try {
Class cls = Class.forName("field2");
Field fld = cls.getField("d");
field2 f2obj = new field2();
System.out.println("d = " + f2obj.d);
fld.setDouble(f2obj, 12.34);
System.out.println("d = " + f2obj.d);
} catch (Throwable e) {
System.err.println(e);
}
}
}


  In this example, the value of the field is changed to the 12.34 d.


9. Using arrays

  This article describes the final use of reflection is to manipulate arrays created. An array is a special type of class in the Java language, a reference to an array can be assigned Object reference. Look at the following example to see how the array works:

import java.lang.reflect.*;

public class array1 {
public static void main(String args[]) {
try {
Class cls = Class.forName("java.lang.String");
Object arr = Array.newInstance(cls, 10);
Array.set(arr, 5, "this is a test");
String s = (String) Array.get(arr, 5);
System.out.println(s);
} catch (Throwable e) {
System.err.println(e);
}
}
}


  Example 10 creates a String array per unit length, the assigned value is a string of five position, the string will finally obtained from the array and printed out.

  The following code provides a more complex example:

import java.lang.reflect.*;

public class array2 {
public static void main(String args[]) {
int dims[] = new int[]{5, 10, 15};
Object arr = Array.newInstance(Integer.TYPE, dims);
Object arrobj = Array.get(arr, 3);
Class cls = arrobj.getClass().getComponentType();
System.out.println(cls);
arrobj = Array.get(arrobj, 5);
Array.setInt(arrobj, 10, 37);
int arrcast[][][] = (int[][][]) arr;
System.out.println(arrcast[3][5][10]);
}
}


  Example created in a 5 x 10 x 15 array of integers, and is in [3] [5] [10] is assigned a value of 37 elements. Note that the multi-dimensional array is actually an array of arrays, for example, after the first Array.get, arrobj is an array of 10 x 15 in. Obtaining a further element therein, i.e. the length of the array 15, and using Array.setInt assigned to its first 10 elements.

  Note that when created the type of the array is dynamic and does not know the type at compile time.

Reproduced in: https: //www.cnblogs.com/licheng/archive/2008/08/25/1276191.html

Guess you like

Origin blog.csdn.net/weixin_34268843/article/details/92631539