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. Detection class:
1.1 reflection's 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.
1.2 Main Methods in Java 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.
Dynamic class loading Using Reflection
Bromon originality, please respect copyright
Recently, I wrote a mobile value-added project in Chengdu, where I am responsible for 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. Everyone who has done similar projects knows that a communication protocol similar to msnp needs to be defined first, 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 the 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 classes for different functions. Each class inherits the operator interface. The client only needs to program the operator interface to avoid a lot of trouble. For example:
Package org. bromon. Reflect .*;
Public class success implements Operator
{
Public java. util. List Act (Java. util. List Params)
{
List result = new arraylist ();