Java reflection mechanism reflection

Source: Internet
Author: User
Tags modifiers
Powerful basic functions of Java ------- Java reflection Favorites

Java reflection-Java reflection

Reflection is one of the characteristics of the Java programming language. It allows running Java programs to check themselves, or "self-Review", and can directly operate on internal properties of the program. For example, you can use it to obtain and display the names of members in the Java class.
This capability of Java may not be used in many practical applications, but it does not exist in other programming languages. For example, Pascal, C, or C ++ cannot obtain information related to function definitions in the program.
Javabean is one of the practical applications of reflection. It allows some tools to operate software components visually. These tools dynamically load and obtain the attributes of Java components (classes) through reflection.
1. A simple example
The following simple example shows 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 );
}
}
}

Run the following statement:
Java dumpmethods java. util. Stack
The output result is as follows:
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)
In this way, the names of Java. util. Stack classes and their delimiters and return types are listed.
This program uses class. forname to load the specified class, and then calls getdeclaredmethods to obtain the list of methods defined in this class. Java. Lang. Reflect. methods is a class used to describe a single method in a class.

2. Start Using Reflection
The class used for reflection, such as method, can be found in the Java. Lang. relfect package. When using these classes, you must follow three steps: the first step is to obtain the java. Lang. Class Object of the class you want to operate on. In the running Java program, java. Lang. Class class is used to describe classes and interfaces.
The following is one of the methods to obtain a class object:
Class C = Class. forname ("Java. Lang. String ");
This statement gets a Class Object of the string class. Another method is as follows:
Class C = int. Class;
Or
Class C = integer. type;
They can obtain information about classes of the basic type. The latter method accesses the pre-defined type field in the encapsulation class of the basic type (such as integer.
The second step is to call methods such as getdeclaredmethods to obtain a list of all methods defined in this class.
Once this information is obtained, you can perform Step 3-use the reflection API to perform such operations, as shown in the following code:
Class C = Class. forname ("Java. Lang. String ");
Method M [] = C. getdeclaredmethods ();
System. Out. println (M [0]. tostring ());
It prints the prototype of the first method defined in string in text format.
In the example below, these three steps will provide examples for Using Reflection to process special applications.
Simulate the instanceof Operator
After getting the class information, 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 {
}
Public class instance1 {
Public static void main (string ARGs []) {
Try {
Class CLS = Class. forname ("");
Boolean b1 = Cls. isinstance (New INTEGER (37 ));
System. Out. println (B1 );
Boolean b2 = Cls. isinstance (new ());
System. Out. println (B2 );
} Catch (throwable e ){
System. Err. println (E );
}
}
}
In this example, a Class Object of Class A is created, and then check whether some objects are instances of Class. INTEGER (37) is not, but new A () is.
3. Find out the Class Method
Find out what methods are defined in a class, which is a very valuable and basic reflection usage. The following code implements 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]);
Class evec [] = M. getexceptiontypes ();
For (Int J = 0; j <evec. length; j ++)
System. Out. println ("exc #" + J + "" + evec [J]);
System. Out. println ("return type =" + M. getreturntype ());
System. Out. println ("-----");
}
} Catch (throwable e ){
System. Err. println (E );
}
}
}
This program first obtains the description of the Method1 class, and then calls getdeclaredmethods to obtain a series of method objects, which respectively describe each method defined in the class, includes the public method, protected method, package method, and private method. If you use getmethods in the program to replace getdeclaredmethods, you can also obtain information about the inherited methods.
After obtaining the method object list, it is not difficult to display the parameter type, exception type, and return value type of these methods. Whether these types are basic or class types can be provided by the objects of the description class in order.
The output result is 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 the constructor Information
The usage of the get class constructor is similar to that of the above method, for example:
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 );
}
}
}
In this example, information about the returned type is not obtained because the constructor does not return the type.
The result of this program running is:
Name = constructor1
Decl class = Class constructor1
-----
Name = constructor1
Decl class = Class constructor1
Param #0 int
Param #1 double
-----
5. Obtain the fields (fields) of the class)
It is also possible to find out which data fields are defined in a class. The following code is doing this:
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 identifier = fieldlist [I];
System. Out. println ("name =" + response. getname ());
System. Out. println ("Decl class =" + response. getdeclaringclass ());
System. Out. println ("type =" + response. GetType ());
Int mod = parser. 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 one. In this example, we use a new thing modifier, which is also a reflection class used to describe the modifier of field members, such as "Private int ". These modifiers are themselves described by integers, And the modifier. tostring is used to return the string descriptions in the "official" Order (such as "static" before "final ). The output of this program is:

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 obtain the method. When obtaining a field, you can only obtain the field information (getdeclaredfields) stated in the current class ), alternatively, you can obtain the fields defined in the parent class (getfields ).

6. Execute the method based on the method name.
The example is related to how to obtain class information. We can also use reflection to do other things, such as executing a method with a specified name. The following example demonstrates 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 );
}
}
}

Note: I personally think it is best to use object methobj = Cls. newinstance (); instead of the underlined bold text. The reason is obvious that if this class and method are clear in advance, you do not need to use reflection.
If a program knows that a method needs to be executed only when it is executed, the method name is specified during the running process of the Program (for example, javaBean development environment will do this), then the above program demonstrates how to do it.
In the preceding example, getmethod is used to find a method with two Integer Parameters named add. After finding the method and creating the corresponding method object, execute it in the correct object instance. When executing this method, you need to provide a list of parameters. In the preceding example, two integer objects with integers 37 and 47 are respectively packaged. The execution method returns an integer object, which encapsulates the return value 84.

7. Create a new object
The constructor cannot be executed as the execution method, because executing a constructor means creating a new object (to be precise, the process of creating an object includes allocating memory and constructing an object ). Therefore, the most similar 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 Based on the specified parameter type and execute it to create a new object instance. This method can be used to dynamically create objects while the program is running, rather than creating objects during compilation, which is very valuable.

8. Change the field value.
Another use of reflection is to change the value of the object data field. Reflection: you can find and change the object field based on the name in a running program. The following example illustrates 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 fields = Cls. getfield ("D ");
Field2 f2obj = new field2 ();
System. Out. println ("d =" + f2obj. D );
Gradient. setdouble (f2obj, 12.34 );
System. Out. println ("d =" + f2obj. D );
} Catch (throwable e ){
System. Err. println (E );
}
}
}
In this example, the field D is changed to 12.34.

9. Use Arrays
The last usage of the reflection described in this article is the Operation Array created. Arrays are a special class type in Java. An array reference can be assigned to an object reference. Observe 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 );
}
}
}
In this example, a string array of 10 units of length is created, a value is assigned to the string at 5th locations, and the string is obtained and printed from the array.
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]);
}
}

In this example, an integer array of 5x10x15 is created, and 37 is assigned to the element in [3] [5] [10. Note that multi-dimensional arrays are actually arrays. For example, after the first array. Get, arrobj is an array of 10x15. Then obtain an element, that is, an array with a length of 15, and assign a value to its 10th elements using array. setint.
Note that the type of the array is dynamic when it is created, and the type is unknown during compilation.

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.