Reflection is one of the features of the Java program development language, which allows the Java program in the run to check itself, or "self-trial", and can directly operate the internal properties of the program. For example, use it to get the name of each member in the Java class and display it.
This capability of Java may not be used in practical applications, but there is no such feature in other programming languages. For example, there is no way to get the function definition related information in the program in PASCAL, C, C .
JavaBean is one of the practical applications of Reflection, which allows some tools to visualize the software components. These tools are dynamically loaded and acquired by the REFLECTION. The properties of the Java component (class) are obtained.
1. A simple example
Consider the following simple example, let us see how the 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 Execute it as follows: Java DumpMethods java.util.stack Its result output is: 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 each method name of the Java.util.stack class and their restrictions and return types. This program uses class.Forname to load the specified class, then call getDeclaredMethods to get the list defined in this class. Java.lang.Reflect.Method is a class for describing a single method in a class. 2. Start using Reflection Classs for Reflection, such as Method, can be found in a java.lang.relFect package. When using these classes, you must follow three steps: The first step is to get the java.lang.class object you want to operate. In the Java program in the run, the classes and interfaces are described with the java.lang.class class. Below is one of the ways to get a Class object: Class C = Class.Forname ("java.lang.string"); This statement gets a class object for a String class. There is also another method, as follows: Class C = int.class; or Class C = Integer.Type; They obtain basic types of information. The latter method is accessed in the basic type of package class (such as Integer) pre-defined Type fields. The second step is to call a method such as getDeclaredMethods to obtain a list of all methods defined in this class. Once this information is obtained, you can perform the third step - using the Reflection API to operate this information, as follows: Class C = Class.Forname ("java.lang.string"); Method m [] = c.getdeclaredMethods (); System.out.println (M [0] .tostring ()); It will print out the first method defined in the string in text. In the following example, the three steps will provide an illustration for special applications using the Reflection. Analog InstanceOf operator After getting class information, usually the next step is to solve some basic problems about the Class object. For example, the class.isinstance method can be used to simulate the 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);}}} In this example, create a Class A class object and then check if some objects are instances A. Integer (37) is not, but new a () is. 3. Find the method of the class To find out what ways defined in a class, this is a very valuable and very basic reflection usage. The following code achieves this usage: Import java.lang.reflect. *; Public class method1 {private int F1 (Object P, int X) throws nullpointersRowteption {if (p == null) throw new nullpointersRexception (); returnx; Public static void main (string args []) {try {class cls = class.forname ("method1"); method method [] = cls.getDeclaredMethods (); for (int i = 0; i After obtaining the list of Method objects, it is not difficult to display the parameter types, exception types, and return value types of these methods. These types are basic types or class types, all can be given in order by the objects described. The result of the output is as follows: Name = f1 DECL Class = Class Method1 PARAM # 0 Class Java.lang.Object Param # 1 int EXC # 0 Class Java.lang.NullPointersRexception Return Type = INT ----- Name = main DECL Class = Class Method1 Param # 0 class [ljava.lang.string; Return Type = Void ----- 4. Get constructor information The usage of the acquisition table constructor is similar to the usage of the above acquisition method, 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 This example has not been able to obtain the relevant information of the return type, that is because the constructor has no return type. The result of this program is: Name = constructor1 DECL Class = Class Constructor1 ----- Name = constructor1 DECL Class = Class Constructor1 Param # 0 int Param # 1 double ----- 5. Get the field of class (domain) Find out which data fields defined in a class are also possible. The following code is doing this: Import java.lang.reflect. *; Public class field1 {private number 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 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 = ----- In the case of obtaining a method, you can only get the field information (getDeclaredFields) declared in the current class, or you can get the field defined in the parent class. 6. Execute the method according to the name of the method The text is here, and the example will be related to how to obtain the information of the class. We can also use reflection to do some other things, such as implementing a method specified by a name. The following example demonstrates this: 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 partpes [] = new class [2]; partypes [0] = integer.Type; Partypes [1] = Integer.Type; method method method ("add", partypes; method2 method = 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 is executing somewhere When you need to perform a method, the name of this method is specified during the running process of the program (for example, this thing in the JavaBean development environment), then the above program demonstrates how to do it. In the above example, getMethod is used to find a method with two integer parameters and namedDD. After finding this method, after the corresponding Method object is created, do it in the correct object instance. When the method is executed, a list of parameters is required, which is two Integer objects that are packaged in the integers 37 and 47 in the previous example. The return of the execution method is also an Integer object, which encapsulates the return value 84. 7. Create a new object For the constructor, it is not possible to perform as the method of execution, because the execution of a constructor means creation a new object (accurately, the process of creating an object includes allocating memory and constructive objects). Therefore, the most similar example of the above example is as follows: 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 according to the specified parameter type and execute it to create a new object instance. Using this method can dynamically create objects when running, not when compiling, this is very valuable. 8. Change the value of the field (domain) There is also a use of REFLECTION to change the value of the object data field. Reflection can find the field of the object from the running program and change it, the following example can explain this: 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 field D is changed to 12.34. 9. Use arrays The last usage of the Reflection described herein is the created an array of operations. Array is a special class type in Java language, and a reference to an array can assign an Object reference. See how the following examples look at the array: 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) The String array of 10 unit lengths was created in the}}}. For the character string of the 5th position, it finally got this string from the array and printed. 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; arrobj = array.get (Arrobj, 5); array.setint (Arrobj, 10, 37 ); Int Arrcast [] [] [] = (int [] [] []) Arr; System.Out.println (Arrcast [3] [5] [10]);}}} The integer array of x 15 and the elements of [3] [5] [10] are values 37. Note that the multidimensional array is actually an array of arrays, for example, after the first array.get, Arrobj is an array of 10 x 15. Furthermore, one element is obtained, that is, an array of length 15 and assigns an array.setInt to its 10th element. Note that the type when creating an array is dynamic, and does not know the type when compiling.