Research and Application of Java reflection mechanism

Source: Internet
Author: User

I. Concepts of reflection:
The concept of reflection was first proposed by Smith in 1982. It mainly refers to the ability of a program to access, detect, and modify its own state or behavior. The proposal of this concept soon led to research on application reflectivity in the computer science field. It was first adopted by the design field of programming language, and has made achievements in LISP and object-oriented aspects. Lead/Lead ++, openc ++, metaxa, and openjava are reflection-based languages. Recently, reflection mechanisms have been applied to Windows, operating systems, and file systems.
Reflection itself is not a new concept. It may remind us of the concept of reflection in optics. Although computer science has given a new meaning to the concept of reflection, in terms of phenomena, they do have some similarities that help us understand. In computer science, reflection is a type of application that can be self-described and self-controlled. That is to say, this type of application uses a mechanism to describe and monitor its own behavior, and according to its own behavior status and results, adjusts or modifies the status and semantics of the behavior described by the application. We can see that, compared with the general reflection concept, reflection in the computer science field not only refers to reflection itself, but also measures taken to reflect the results. All systems that adopt reflection mechanisms (I .e. reflection Systems) want to make their implementations more open. It can be said that all systems implementing reflection mechanisms are open, but open systems do not necessarily adopt reflection mechanisms. Openness is a necessary condition for reflection systems. In general, the reflection system must meet both the open conditions and the cause of connection (causally-connected ). The so-called cause connection refers to the situation where the changes in the self-description of the reflection system can be immediately reflected in the actual status and behavior at the underlying level of the system, and vice versa. Open connection and cause connection are two basic elements of the reflection system. 13700863760
In Java, reflection is a powerful tool. It allows you to create flexible code that can be configured during running without the need for source representative links between components. Reflection allows us to enable our program code to access the internal information of classes loaded into the JVM when writing and executing, rather than the code for class collaboration selected in the source code. This makes reflection a major tool for building flexible applications. However, it should be noted that, if improperly used, reflection costs are high.
Ii. Class reflection in Java:
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. 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.
1
. Check class:
1.1 reflection
Working mechanism
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.
Java 1.2
Main Methods in class reflection
Java. Lang. class provides four independent reflection calls for any of the following three components: constructor, field, and method to obtain information in different ways. All calls follow a standard format. The following is a set of reflection calls used to find constructors:
L constructor getconstructor (class [] Params) -- obtains a common constructor that uses special parameter types,
L constructor [] getconstructors () -- obtain all public constructors of the class
L constructor getdeclaredconstructor (class [] Params) -- obtains constructors using specific parameter types (unrelated to the access level)
L constructor [] getdeclaredconstructors () -- obtain all constructors of the class (irrelevant to the access level)
The class reflection call for obtaining field information is different from the call for accessing constructor. The field name is used in the parameter type array:
L field getfield (string name) -- Obtain the named public field
L field [] getfields () -- obtain all public fields of the class
L field getdeclaredfield (string name) -- Obtain the name field of the class declaration
L field [] getdeclaredfields () -- obtain all fields declared by class
Function used to obtain method information:
L method getmethod (string name, class [] Params) -- use a specific parameter type to obtain the named public Method
L method [] getmethods () -- obtain all public methods of the class
L method getdeclaredmethod (string name, class [] Params) -- Obtain the class declaration naming method by using the parameter type of close-up.
L method [] getdeclaredmethods () -- obtain all methods declared by class
 
1.3
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.
2
. Processing object:
To create a development tool such as debugger, you must discover filed values. The following are three steps:
A. Create a Class Object
B. Create a Field object through getfield
C. Call the field. getxxx (object) method (XXX is int, float, etc. If it is an object, it is omitted; object is an instance ).
For example:
Import java. Lang. Reflect .*;
Import java. AWT .*;
Class sampleget {
Public static void main (string [] ARGs ){
Rectangle r = new rectangle (100,325 );
Printheight (R );
}
Static void printheight (rectangle R ){
Field heightfield;
Integer heightvalue;
Class C = R. getclass ();
Try {
Heightfield = C. getfield ("height ");
Heightvalue = (integer) heightfield. Get (R );
System. Out. println ("height:" + heightvalue. tostring ());
} Catch (nosuchfieldexception e ){
System. Out. println (E );
} Catch (securityexception e ){
System. Out. println (E );
} Catch (illegalaccessexception e ){
System. Out. println (E );
}
}
}
 
Iii. Security and reflection
:
Security is a complicated issue when dealing with reflection. Reflection is often used by framework code. Because of this, we may want the framework to fully access the code without the need to consider general access restrictions. However, in other cases, uncontrolled access brings serious security risks, such as running code in an untrusted code sharing environment.
Due to these conflicting requirements, the Java programming language defines a multi-level method to handle reflection security. The basic mode is to impose the same limitations on reflection as source code access:
N access from any location to public components
Class N has no access to private components.
N limited access to protected and packaged (default access) components
At least sometimes, there is a simple way around these limits. We can extend a common basic class java. Lang. Reflect. accessibleobject in the class we write. This class defines a setaccessible method that enables or disables access detection for one of these classes. The only problem is that if the security manager is used, it will detect whether the code that is disabling access detection permits this. If not, the security manager throws an exception.
The following is a program that uses reflection on an instance of the twostring class to show that security is running:
Public class reflectsecurity {
Public static void main (string [] ARGs ){
Try {
Twostring Ts = new twostring ("A", "B ");
Field field = Clas. getdeclaredfield ("m_s1 ");
// Field. setaccessible (true );
System. Out. println ("retrieved value is" +
Field. Get (insT ));
} Catch (exception ex ){
Ex. printstacktrace (system. Out );
}
}
}
If we compile this program and run it directly from the command line without using any specific parameters, it will throw an illegalaccessexception exception in the field. Get (insT) Call. If we do not comment on the field. setaccessible (true) line of code, re-compile and re-run the code, which will be compiled successfully. Finally, if we add the JVM parameter-djava. Security. Manager in the command line to implement the security manager, it still cannot be compiled unless we define the permission for the reflectsecurity class.
Iv. Reflection Performance
:
Reflection is a powerful tool, but there are also some shortcomings. A major drawback is the impact on performance. Reflection is basically an interpreted operation. We can tell JVM what we want to do and what it meets our requirements. This type of operation is always slower than simply performing the same operation.
The following Program is an example of field access performance testing, including basic testing methods. One form of test field access for each method -- accesssame works with member fields of the same object, and accessother uses fields of another object that can be directly accessed, accessreflection uses fields of another object that can be accessed through reflection. In each case, the method executes the same computation-a simple addition/Multiplication sequence in a loop.
The procedure is as follows:
Public int accesssame (INT loops ){
M_value = 0;
For (INT Index = 0; index <loops; index ++ ){
M_value = (m_value + additive_value )*
Multiplier_value;
}
Return m_value;
}
 
Public int accessreference (INT loops ){
Timingclass timing = new timingclass ();
For (INT Index = 0; index <loops; index ++ ){
Timing. m_value = (timing. m_value + additive_value )*
Multiplier_value;
}
Return timing. m_value;
}
 
Public int accessreflection (INT loops) throws exception {
Timingclass timing = new timingclass ();
Try {
Field field = timingclass. Class.
Getdeclaredfield ("m_value ");
For (INT Index = 0; index <loops; index ++ ){
Int value = (field. getint (timing) +
Additive_value) * multiplier_value;
Field. setint (timing, value );
}
Return timing. m_value;
} Catch (exception ex ){
System. Out. println ("Error Using Reflection ");
Throw ex;
}
}
In the preceding example, the test program repeatedly calls each method and uses a large number of loops to measure the result by average time of multiple calls. The average value does not include the first call time of each method. Therefore, the initialization time is not a factor in the result. The following figure clearly shows the access time of each method field:
Figure 1: field access time
:
We can see that in the first two figures (Sun JVM), the execution time of reflection exceeds 1000 times that of direct access. By comparison, ibm jvm may be a little better, but the reflection method still needs to be more than 700 times longer than other methods. There is no significant difference in time between the other two methods on any JVM, but ibm jvm is almost twice faster than Sun JVM. Most likely, this difference reflects the professional Optimization of sun hot spot JVM, which performs poorly in simple benchmarking. Reflection performance is an important aspect of Sun's 1.4 JVM development. It is displayed in the reflection method call results. In terms of the performance of such operations, Sun 1.4.1 JVM shows great improvements over version 1.3.1.
If a similar timing test program is written for the creation of objects using reflection, we will find that the differences in this case are not as significant as in the case of field and method calls. Use newinstance () to create a simple Java. lang. the time consumed by the object instance is about 12 times that of using new object () on Sun 1.3.1 JVM, four times that of IBM 1.4.0 JVM, but two times that of Sun 1.4.1 JVM. Use array. newinstance (type, size) consumes twice the time to create an Array Using New Type [size] on any tested JVM. As the array size increases, the difference gradually decreases.
Conclusion
:
Java reflection provides a multi-functional method for dynamically linking program components. It allows programs to create and control objects of any class (according to security restrictions), without the need to hard-code the target class in advance. These features make reflection especially suitable for creating libraries that work with objects in very common ways. For example, reflection is often used in frameworks where the continuously stored object is in a database, XML, or other external format. Java reflection is very useful, which enables the class and data structure to Dynamically Retrieve relevant information by name and allow such information to be operated in the running program. This feature of Java is very powerful and is not available in other common languages, such as C, C ++, FORTRAN or Pascal.
Reflection has two disadvantages. The first is performance issues. Reflection is much slower than direct code for field and method access. The degree of performance problems depends on how reflection is used in the program. If it is a relatively small part of the program running, slow performance will not be a problem. The reflection operation shown in the timing chart in the worst case of the test takes only a few microseconds. Performance issues are crucial only when reflection is used in the core logic of performance-critical applications.
One of the more serious disadvantages of many applications is that reflection will blur what actually happens inside the program. Programmers want to see the program logic in the source code, reflection and other technologies that bypass the source code will cause maintenance problems. Reflection code is more complex than the corresponding direct code, as seen in code instances with better performance. The best solution to these problems is to use reflection conservatively-only where it can actually increase flexibility-record its use in the target class.
 
 
Exploitation
Reflection
Implementation
Class
Dynamic Loading
Bromon originality, please respect copyright
I recently wrote
Mobile value-added Projects
In charge of the backend server. The function is very simple. A mobile phone user opens a socket through GPRS to connect to the server, and I will respond based on the data transmitted by the user. Done
Class
The project owner must know that the first thing to define is
Class
Similar to msnp communication protocols, but today's topic is how to design this system with high scalability. As this project has not conducted well-developed customer communication and demand analysis, there will certainly be many extensions in the future, and the communication protocols will surely become larger and larger, as a less diligent person, I certainly don't want to modify the program later, so this project is a good opportunity to practice object-oriented design.
First define an interface to isolate
Class
:
Package org. bromon. Reflect;
Public interface operator
{
Public java. util. List Act (Java. util. List Params)
}
Based on the principle of the design pattern, we can write different
Class
, Each
Class
All inherit the operator interface. The client only needs to program the operator interface to avoid a lot of trouble. For example
Class
:
Package org. bromon. Reflect .*;
Public class success implements Operator
{
Public java. util. List Act (Java. util. List Params)
{
List result = new arraylist ();
Result. Add (new string ("operation successful "));
Return result;
}
}
We can also write many other
Class
But there is a problem, the interface cannot be instantiated, and we must manually control which
Class
This is unpleasant. If you can pass a parameter to the application, let yourself choose to instantiate
Class
To execute its act method, which makes our work much easier.
Fortunately, I use Java. Only Java provides
Reflection
Mechanisms, or internal mechanisms, can meet our unreasonable requirements. Compile a configuration file EMP. properties:
# Successful response
1000 = Success
# Sending common text messages to customers
2000 = Load
# The customer sends a common text message to the server
3000 = store
The key name in the file is the message header that the customer will send to me. The customer will send 1000 to me, then I will execute success
Class
The Act method,
Class
If 2000 is sent to me, load
Class
In this way, the system fully complies with the open and closed principles. If you want to add new functions, you do not need to modify the existing code. You only need to add the corresponding rules in the configuration file, then write a new
Class
The implementation of the Act method is OK. Even if I discard this project, it will be well extended in the future. Such a system has excellent scalability and insertion ability.
The following example shows the function of dynamic loading. During execution, the program knows which one should be instantiated.
Class
:
Package org. bromon. Reflect .*;
Import java. Lang. Reflect .*;
Public class testreflect
{
// Load the configuration file and query the corresponding message header
Class
Name
Private string loadprotocal (string header)
{
String result = NULL;
Try
{
Properties prop = new properties ();
Fileinputstream FCM = new fileinputstream ("EMP. properties ");
Prop. Load (FS );
Result = prop. getproperty (header );
FCM. Close ();
} Catch (exception E)
{
System. Out. println (E );
}
Return result;
}
// Respond to and use the message
Reflection
Import the corresponding
Class
Public String response (string header, string content)
{
String result =
Null
;
String S =
Null
;
Try

{
/*
* Import the property file EMP. properties to query the corresponding Header
Class
Name
* Pass
Reflection
Mechanism for dynamic loading matching
Class
, All
Class
All are isolated by Operator Interfaces.
* You can modify attribute files and add new
Class
(Inheriting the msgoperator Interface) to extend the Protocol
*/
S = "org. bromon. Reflect." +
This
. Loadprotocal (header );
// Load
Class
Class C = Class. forname (s );
// Create
Class
Examples
Operator Mo = (operator) C. newinstance ();
// Construct the parameter list
Class Params [] =
New
Class [1];
Params [0] = Class. forname ("Java. util. List ");
// Query the act Method
Method M = C. getmethod ("act", Params );
Object ARGs [] =
New
Object [1];
ARGs [0] = content;
// Call the method and obtain the returned result
Object returnobject = M. Invoke (Mo, argS );
}
Catch
(Exception E)
{
System. Out. println ("Handler-response:" + E );
}
Return
Result;
}
Public static void main (string ARGs [])
{
Testreflect TR = new testreflect ();
Tr. Response (ARGs [0], "message content ");
}
}
Test: Java testreflect 1000
This program is programmed for operator, so no modifications are required to directly provide load and store
Class
You can call parameters 2000 and 3000.
With this internal saving mechanism, the interface function can be played to the extreme, and the design model can also reflect the power, not just for chatting after meals.

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.