Class reflection mechanism in Java

xiaoxiao2021-03-06  64

Class reflection mechanism in Java

First, the concept of reflection:

The concept of reflection is first proposed by Smith in 1982, mainly means that the program can access, detect and modify its state or behavior. This concept is raised soon triggered research on application reflexibility in computer science. It is first adopted by the design area of ​​the program language and achieves grades in LISP and object-oriented. Among them, Lead / Lead , OpenC , Metaxa and Openjava are based on reflex mechanisms. Recently, reflective mechanisms are also applied to window systems, operating systems, and file systems.

Reflection itself is not a new concept, which may make us in the optical reflection concept, although computer science gives the new meaning of reflection concept, but from the phenomenon, they do have some communication, these Help our understanding. In the field of computer science, reflection refers to a class of applications that are self-describing and self-control. That is, this type of application implements a self-representation and monitoring of its own behavior by adopting a mechanism, and can adjust or modify the status of the behavior described in the application according to the status and results of their own behavior. Related semantics. It can be seen that the reflection of the computer science field is not single referred to the reflection itself compared to the general reflection concept, and the measures taken to the reflection result. All systems (ie, reflection systems) that use reflex mechanisms want to make the system's implementation more open. It can be said that the system that realizes the reflective mechanism has openness, but an open system does not necessarily adopt a reflective mechanism, and the openness is the necessary conditions for the reflective system. In general, the reflection system must meet the cause connection (Causally-Connected) in addition to the open condition. The so-called reason connection refers to the changes that the change in the reflective system can immediately reflect the actual state and behavior of the underlying layer of the system, and vice versa. Openness and reasons are two basic elements of the reflective system. 13700863760

In Java, reflection is a powerful tool. It enables you to create flexible code that can be assembled at runtime without having to link between components. Reflection allows us to write to the internal information of the class loaded into the JVM when writing and execution, instead of the selected class collaboration in the source code. This makes reflections become the main tool for building flexible applications. However, it is important to note that if improper use, the reflection costs are high.

Second, the class reflection in Java:

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. 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 .

1. Detection class:

1.1 REFLECTION work mechanism

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

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.

1.2 Main Methods in Java Reflections

For any class in the following three-class components - constructor, fields, and methods - java.lang.class provide four separate reflection calls to obtain information in different ways. The call follows a standard format. The following is a set of reflection calls for finding constructor:

l Constructor getConstructor (class [] params) - Get a public constructor using a special parameter type,

l Constructor [] getConstructors () - Get all public constructors of the class

l Constructor getDeclaredConstructor (class [] params) - Get constructor using a specific parameter type (independent of access level)

l Constructor [] getDeclaredConstructors () - Get all constructor of the class (independent of access level)

Class reflection calls for field information are different from those calls used to access constructors, and the field name is used in the parameter type array:

l Field getfield (String Name) - Get a named public field

l Field [] getfields () - Get all public fields of the class

l Field getDeclaredfield (String Name) - Get naming fields for class declarations

l Field [] getDeclaredfields () - Get all fields for class declarations

Used to obtain method information functions:

l Method getMethod (String Name, Class [] Params - Get Named Public Method LMMETHOD [] getMethods () - Get all public methods of class

l Method getDeclaredMethod (String Name, Class [] Params) - Use the close-up parameter type to get the name of the name declaration

l method [] getDeclaredMethods () - all methods for getting class declarations

1.3 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.

2. Treatment object:

If you want to make a development tool like Debugger, you have to find FileD Values, the following is three steps:

a. Create a Class object b. Create a field object C via getField C. Call the field.getxxx (Object) method (xxx is int, float, etc. If it is an object; 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 (securityExcect e) {system.out.println (e);} catch (IllegalaccessException E) {system.out.println (e);}}} 3, security and reflection:

Security is a more complicated problem when processing reflection. Reflection is often used by the frame type code. For this, we may wish that the framework can be fully access code without considering conventional access restrictions. However, in other cases, uncontrolled access will bring serious security risks, such as runtime when codes run in an environment where you are not worth trust.

Due to these mutual contradictory needs, Java programming languages ​​define a multi-level method to handle reflection security. The basic mode is the same restrictions on the implementation of reflection and the application of source code:

N from an access to the public components from any location

Noths from themselves without any access to private components

N limited access to protected and packaged (default access) components

But at least some, there is still a simple method around these limits. We can extend a normal basic class java.lang.Reflect.accessibleObject class in the class we have written. This class defines a setAccessible method that enables us to start or close access detection of instances of these classes in these classes. The only problem is that if the security manager is used, it will detect whether the code that is closing access detection is licensed. If not permitted, the security manager throws an exception.

Here is a program that uses reflection on one instance of the TwoString class to display 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, do not run from the command line without using any specific parameters, which will throw an IllegalaccessException in the field .get (inst) call. If we don't comment the field.setaccessible (TRUE) code, then recompile and re-run the code, it will be compiled. Finally, if we add JVM parameters to the command line to implement the security manager, it will not be compiled unless we define the license permission for the ReflectSecurity class. Fourth, reflection performance:

Reflection is a powerful tool, but there are some shortcomings. A main disadvantage is that there is an impact on performance. Using reflection is basically an explanation, we can tell JVM, what we want to do and it meets our requirements. This type of operation is always slower than only the same operation directly.

The following program is an example of field access performance test, including basic test methods. Each method test field access is a form - AccessSame collaborate with the member field of the same object, Accessother uses a field of another object that can be accessed, and AccessReflection uses a field that can be reflected another object. In each case, the method performs the same calculation - a simple / multiplication order in the loop.

The procedure is as follows:

Public int accesssame (int loops) {

m_value = 0;

For (int index = 0; 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

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

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 above example, the test program repeats each method, using a large number of cycles, thereby measuring the time measurement results that are called multiple times. The average value does not include each method for the first time called, so the initialization time is not a factor in the result. The following figure clearly shows us the time of each method field:

Figure 1: Field access time: We can see: In the first two pairs (Sun JVM), the execution time of the reflection exceeds 1000 times the direct access. By comparison, IBM JVM may slightly, but the reflection method still needs more than 700 times longer than other methods. There is no significant difference in time between other two methods on JVM, but IBM JVM is almost twice as fast than Sun JVM. The most likely this difference reflects the professional optimization of Sun Hot Spot JVM, which is very bad in simple benchmarks. Reflectivity is an aspect of the SUN development 1.4 JVM, which is displayed in the reflection method call. In terms of such operations, Sun

1.4.1

JVM shows a large improvement than version 1.3.1.

If a similar timing test program is written for the object to create a reflection, we will find that the difference in this case is not as significant as the field and method calls. Creating a simple java.lang.Object Execution is approximately at Sun using newInstance () calls.

1.3.1

12 times the use of new object () on the JVM, it is four times that of IBM 1.4.0 JVM, only two of Sun 1.4.1 JVM. Creating an array-consuming time using array.newinstance (type, size) is twice that of any test's JVM using new type [size], with the increase in the size of the array, the difference is gradually narrowed.

Conclusion:

Java language reflection provides a multi-functional way for dynamic linking program components. It allows programs to create and control any class objects (depending on security restrictions), there is no need to hardly encode the target class in advance. These features make reflexes especially suitable for creating libraries that work with objects in very common ways. For example, reflecting is often used in a framework that continuously stores a database, XML, or other external format. Java Reflection is very useful, which enables class and data structures to dynamically retrieve relevant information by name and allow this information to be operated in the running program. This feature of Java is very powerful, and other common languages, such as C, C , Fortran or PASCAL, etc.

But there are two shortcomings in reflection. The first is a performance problem. Reflection is slower than the direct code when accessing to fields and methods. Performance issues Depending on how the program is reflected in the program. If it is a relatively little part of the program run, the slow performance will not be a problem. Even if the reflection operation shown by the worst case in the worst case in the test consumes only a few microseconds. Performance issues are only critical to use only in the core logic of performance critical applications.

A more serious disadvantage in many applications is that the use of reflexations will actually happen within the fuzzy program. The programmer wants to see the logic of the program in the source code, and the technique of reflection bypassing the source code will bring maintenance issues. The reflection code is more complicated than the corresponding direct code, as seen in the code instance of performance comparison. The best solution to these issues is to conservatively use reflection - only where it can truly increase flexibility - record their use in the target class.

Dynamic loading of the class with reflection

Bromon original, please respect the copyright

I recently wrote a mobile value-added project in Chengdu, and I was responsible for the background server. The function is very simple, and the mobile phone user opens the socket with the server via GPRS, and I respond according to the data passed by the user. Brothers who have done similar projects must know that first, a communication protocol similar to MSNP is needed, but today's topic is how to design this system highly scalable. Since this project itself did not have a relatively complete customer communication and demand analysis, there will be many functions in the future, and the communication agreement will definitely be more and more huge, and I as a less diligent person, of course, I don't want to go later. To modify the written program, 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 principle of design patterns, we can write different classes for different functions. Each class inherits the Operator interface, and the client only needs to program a lot of trouble for Operator interface. For example, this 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));

Return Result;

}

}

We can also write many other classes, but there is a problem, the interface cannot be instantiated, we must manually control which class, which is very unhappy, if you can pass a parameter to the application, let yourself choose to instantiate one Class, execute its ACT method, then our work is much easier.

Very lucky, I am using Java, only Java provides such reflex mechanisms, or the internal provincial mechanism, can achieve our unreasonable requirements. Write a configuration file Emp.properties:

# Successful response

1000 = SUCCESS

# Send a normal text message to customers

2000 = LOAD

# 客户 客户 Send a normal text message to the server

3000 = Store

The key name in the file is the message header that the customer will send it. The customer sends 1000 to me, then I will execute the ACT method of the Success class. If you send me 2000, then execute the ACT method of the Load class, so The system is fully compliant with the opening and closing principle. If you want to add a new function, you don't need to modify the existing code, just add the corresponding rules in the configuration file, then write new classes, implement the ACT method is OK, even if I abandon This project is going, it can also expand well in the future. Such systems have very good scalability and insertability.

The following example reflects the dynamic load function, and the program knows which class should be instantiated during the execution process:

Package org.bromon.reflect. *;

Import java.lang.reflect. *;

Public class testReflect

{

/ / Load the configuration file, query the class name corresponding to the message header

Private string loadProtocal (String Header)

{

String result = null;

Try

{

Properties Prop = New Properties ();

FileInputStream Fis = New FileInputStream ("Emp.Properties");

Prop.Load (FIA);

Result = prop.getProperty; Header;

fis.close ();

} catch (Exception E)

{

System.out.println (e);

}

Return Result;

}

// Response for messages, use reflection imported into the corresponding class

Public String Response (String Header, String Content)

{

String result = null;

String s = null;

Try

{

/ *

* Import Properties File Emp.properties, query the name of the class corresponding to Header

* Dynamically load matching class by reflective mechanism, all classes are isolated by Operator interface

* You can extend the protocol * / by modifying the properties file

S = "org.bromon.reflect." this.loadProtocal (header);

// Load class

Class C = Class.Forname (s);

// Create a class

Operator mo = (operator) C.NewInstance ();

// Construct parameter list

Class params [] = new class [1];

Params [0] = Class.Forname ("java.util.list");

// Query ACT method

Method M = C.getMethod ("ACT", PARAMS);

Object args [] = new object [1];

Args [0] = Content;

// Call the method and get the return

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 for Operator programming, so there is no need to do any modifications, directly provide the LOAD and Store class, you can support the call of 2000, 3000 to do parameters.

With such an internal provincial mechanism, you can use the role of the interface to the extreme, and the design model can also reflect the power, not just after our meals.

转载请注明原文地址:https://www.9cbs.com/read-86081.html

New Post(0)