Class reflection mechanism in Java

Source: Internet
Author: User
Class reflection mechanism in Java
 
 
I. Concept 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. Reflection is a powerful tool in 13700863760java. 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 features of the Java programming language. It allows the running Java program to check itself, or "self-Review ", and can directly operate on the 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 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 );
}
}
} Run the following statement: Java dumpmethods Java. util. STACK: 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) to list Java. util. the methods of stack classes and their delimiters and return types. 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 for any of the following three components-constructor, field, and method-java. lang. class provides four independent reflection calls to obtain information in different ways. All calls follow a standard format. The following is a set of reflection calls used to find constructor: l constructor getconstructor (class [] Params) -- get a public constructor using a special parameter type, l constructor [] getconstructors () -- Get all the common constructor l constructor getdeclaredconstructor (class [] Params) of the class -- get the constructor (which is independent of the access level) l constructor [] getdeclaredconstructors () -- obtains all constructors of A Class (unrelated to the access level). Class reflection calls for obtaining field information are different from those for accessing constructors. Field names are used in parameter type Arrays: l field getfield (string name) -- Obtain the named public field l field [] getfields () -- Obtain There is a public field l field getdeclaredfield (string name) -- get the name field of the class declaration l field [] getdeclaredfields () -- get all fields of the class declaration for obtaining method information function: l method getmethod (string name, class [] Params) -- use a specific parameter type to obtain the named public method l method [] getmethods () -- obtain all common methods of the class l method getdeclaredmethod (string name, class [] Params) -- use the parameter type of the close-up to obtain the class declaration naming method l method [] getdeclaredmethods () -- Get all methods declared by Class 1.3 Start Using Reflection: class for reflection, such as method, can be in Java. l Ang. 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 class information 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 operate on this information, 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 objects: If you want to be a development tool such as debugger, you must be able to find 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 );
}
}
} 3. Security and reflection: security is a complicated problem 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 of the Class N access from external components of the Class N access from private components N limited access to protected and packaged (default access) components but at least sometimes, there is also a simple method around these limitations. 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. Reflection is used 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 = 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 without using any specific parameters to run directly from the command line, it will be in field. get (in St) An illegalaccessexception exception is thrown in the 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 program 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;} pub LIC int accessreflection (INT loops) throws exception {timingclass timing = new timingclass (); try {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 reflecti On "); throw ex ;}} in the above 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 figure below 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 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 is original. Please respect copyright. Recently, I wrote a mobile value-added project in Chengdu. I am 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. 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)} according to the design pattern principle, 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 (); result. add (new string ("operation successful"); return result ;}} we can write many other classes, but there is a problem that the interface cannot be instantiated, we must manually control the specific class to be instantiated, which is quite uncomfortable. If we can pass a parameter to the application, let ourselves choose to instantiate a class and execute its act method, that makes our work easier. Fortunately, I am using Java. Only Java provides such a reflection mechanism, or an introspection mechanism, to meet our unreasonable requirements. Compile a configuration file EMP. properties: # successful response 1000 = success # Send a common text message to the customer 2000 = load # The customer sends a common text message to the server 3000 = the key name in the store file is the message header that the customer will send to me, if the client sends 1000 to me, then I will execute the act Method of the success class. Similarly, if the client sends 2000 to me, it will execute the act Method of the load class, in this way, the system fully complies with the open and closed principles. To add new functions, you do not need to modify the existing code. You only need to add corresponding rules in the configuration file, and then write new classes, the implementation of the Act method is OK. Even if I discard this project, it will be very scalable in the future. Such a system has excellent scalability and insertion ability. The following example shows the dynamic loading function. During execution, the program knows which class should be instantiated: Package Org. bromon. reflect. *; import Java. lang. reflect. *; public class testreflect {// load the configuration file and query the class name private string loadprotocal (string header) {string result = NULL; try {properties prop = new properties (); fileinputstream FD = new fileinputstream ("EMP. properties "); prop. load (FCM); Result = prop. getproperty (header); FCM. close ();} catch (exception e) {system. out. println (E);} retur N result;} // responds to a message and imports the corresponding public string response (string header, string content) {string result = NULL; string S = NULL Using Reflection; try {/** import the property file EMP. properties: queries the name of the class corresponding to the header * dynamically loads the matching class through the reflection mechanism, all classes are isolated by the operator interface * You can extend the Protocol by modifying the attribute file and adding a new class (inheriting the msgoperator Interface) */S = "org. bromon. reflect. "+ this. loadprotocal (header); // load class C = Class. forname (s); // create a class case operator Mo = (operator) C. newinstance (); // constructor parameter list class Params [] = new class [1 ]; Params [0] = Class. forname ("Java. util. list "); // query the act method M = C. getmethod ("act", Params); object ARGs [] = new object [1]; ARGs [0] = content; // call the method and obtain the returned 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 is for opera Tor programming, so there is no need to make any changes, directly provide load and store classes, you can support 2000, 3000 for parameter calls. 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 dinner.

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.