Reflection, Java soul

xiaoxiao2021-03-06  38

Reflection allows your program code to access internal information loaded into the class in the JVM, allowing you to write and execute, rather than code collaboration in the source code. This makes reflections become the main tool for building flexible applications. But to note that - if improper use, the cost of reflection is high. In a Java Platform Series, Software Consultants Dennis Sosnoski introduces how to use reflections and certain related costs. You will also find how the Java Reflection API enables you to associate with the runtime. In "Dynamics of Java Programming, Part 1," I introduced you to Java programming classes and classes. This article introduces some information about Java binary format. This month I will explain the basis of using Java reflection API to access and use some of the same information at runtime. In order to make developers who are well known to reflex, I will include reflex performance in the article to compare with direct access. Use reflection different from conventional Java programming, where it is in metadata-describes data collaboration of other data. The special type of Java language reflected access is a description of the JVM and objects. Reflection allows you to get a wide range of information. It even enables you to read and write fields, call the method of clasping the class selected. Reflection is a powerful tool. It enables you to create flexible code that can be assembled at runtime without having to link between components. But some aspects of reflection have some questions. In this article, I will discuss why you may not want to use reflections in the program, and the reason you should do. After understanding the analysis of the weighing, you can decide whether it is greater than the disadvantage. The beginning of the initiator's class use reflection is always a java.lang.class instance. If you want to collaborate with pre-defined classes, the Java language provides a simple and shortcut to obtain Class instances: Part 1, "Class and class load"

Code: Class Clas = Myclass.class;

When you use this technology, all work involved in the load is behind the scenes. However, this method is not suitable if you need to read the class name from some external sources at runtime. In fact, you need to use a class loader to find class information. The following introduces a method:

Code: // "name" is the class name to load class clas = null; try {clas = class.forname (name);} catch (classnotfoundexception ex) {// Handle Exception Case} // use the loading class

If you have already loaded, you will get existing Class information. If the class is not loaded, the class loader will now load and return to the newly created class instance. Class-based reflection Class objects provide you with all basic hooks of reflection of access type metadata. Such metadata includes information about class itself, such as packets and classes, and interfaces implemented by this class. It also includes details of the constructor, fields, and methods defined. These final projects are the most frequently used items in programming, so I will give some instances collaborated with them later in this section. 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: Constructor getConstructor (class [] params) - Get public constructors using special parameter types, constructor [] getConstructors () - Get all public constructors of classes Constructor getDeclaredConstructor (class [] params) - Get all constructor (] getDeclaredConstructors () for the use of specific parameter types (unrelated to access level) - All constructor (unrelated to access level) Returns one or more java.lang.Reflect.constructor functions. This constructor class defines the NewInstance method. It uses a set of objects as its unique parameters and then returns the newly created original class instance. This group object is the parameter value for constructing the function call. As an example of explaining this workflow, you have a TwoString class and a constructor using a pair of strings, such as Listing 1: Listing 1: Class code created from a pair of strings: public class twostring {private string M_S1, M_S2; Public Twostring (String S1, String S2) {m_s1 = S1; M_S2 = S2;}}

The code in Listing 2 gets a constructor and uses it to create an instance of the TwoString class using strings "a" and "b": Listing 2: Reflection of the constructor

Code: class [] Types = new class [] {string.class, string.class}; constructor cons = twnowString.class.getConstructor (Types); object [] args = new object [] {"a", "b" }; Twostring ts = cons.newinstance (args);

The code in Listing 2 ignores a variety of possible exceptions that have been thrown by different reflection methods. Exception record in the Javadoc API description, so I will ignore them in all program instances for the sake of brevity. Although I discuss constructor theme, Java programming language also defines a special shortcut you can use to create an instance that creates a class without parameter (or default) constructor. This shortcut is embedded in the Class definition, as follows: Object newInstance () - Creating a new instance using the default function Even if this method only allows you to use a special constructor, if this is what you need, then It will provide a very convenient shortcut. This technology is particularly useful when collaborating with JavaBeans, and JavaBeans need to define public and non-parameter constructor. Class reflection calls that obtain field information by reflecting the field information are different from those used to access constructors, using field names in the parameter type array: Field getfield (String Name) - Get Named Public Field Field [] getfields () - Get all public fields of the class Field getDeclaredfield (String Name) - Named Field Field [] getDeclaredfields () - Get all the fields of the class declaration, although similar to the constructor, still in terms of field There is an important difference: the first two variables returns information that can be accessed by the class access - even though they come from ancestors. The latter two variables return to the information of the class directly declared - unrelated to the type of access to the field. Call the returned java.lang.Reflect.field instance defines all the Getxxx and SetXXx methods for all primary types, and the general GET and SET methods that collaborate with the object reference. You can choose an appropriate method according to the actual field type, and the getxxx method will automatically process extension transitions (such as using the GetInt method to retrieve a byte value). Listing 3 Displays an example of using a field reflection method, adds an INT field of the object in the format of the name: Listing 3: Add a field code by reflection: public int incrementfield (String name, Object obj) throws ... {Field Field = obj.getClass (). getDeclaredfield (name); int value = field.getint (obj) 1; Field.setint (Obj, value); return value;}

This approach begins to show some flexibility to reflex. Unlike specific class collaboration, INCREMENTFIELD uses the GetClass method of the incoming object to find class information, then find the named field directly in this class. Class reflection calls for method information by reflecting increase methods are very similar to the call to constructors and fields: Method getMethod (String name, class [] params - use specific parameter types to get naming public methods Method [] GetMethods () - Get all public methods for class Method getDeclaredMethod (String Name, Class [] params) - Use the close-up parameter type, get the name of the name declaration Method [] getDeclaredMetHods () - Get all the category declarations All Methods The first two variables returned to information that can be accessed through class - even though they come from ancestral classes. The information of the latter two variables returns the class declaration method, which is independent of the type of access to the method. The Java.lang.Reflect.Method instance that calls returns is defined to call the method on one instance of the class being defined. This type of invoke method uses two parameters to provide a class instance and parameter value array for call. Listing 4 further illustrates a field instance to display an example of the method that is running is running. This method adds an int JavaBeaN property that defines a GET and SET methods. For example, if the object defines a getCount and SetCount method for an integer count value, you can pass "count" as a Name parameter in a call to increase this value. Listing 4: Add a JavaBeaN property code by reflection: public int incrementproperty (String name, object obj) {string prop = character.touppercase (name.charat (0)) Name.Substring (1); string mname = "get" Prop; Class [] Types = new class [] {}; method method = obj.getClass (); getMethod (mName, Types); object result = method.invoke (Obj, new object [0]); int value = (Integer) .intValue () 1; MNAME = "set" prop; type = new class [] {int.class}; method = obj.getClass (); getMethod (MNAME, TYPES); Method. Invoke (Obj, New Object [] {new integer (value)}; return value;}

In order to follow the JavaBeans practice, I change the initial of the property name to uppercase, then consider Get to create a read method name, set to create a write method name. The JavaBeans read method only returns a value, and the write method uses the value as the unique parameter, so I specify the method's parameter type for matching. Finally, the convention requires the method for public, so I use the lookup format to find public methods that can be called on the class. This example is the first instance I use reflection to pass the primary value, so let's see how it works. The basic principle is simple: whenever you need to deliver the primary value, just use an example of the corresponding package class (defined in the java.lang package) to replace this primary value. This can be applied to calls and returns. Therefore, when I call the GET method in the instance, I expect the results for the actual int attribute value of Java.lang.integer package. The reflection array array is an object in the Java programming language. Like all objects, they have classes. If you have an array, use the standard getClass method, you can get the class of the array, just like any other object. However, the class is different from other types of objects without existing instances. Even if you have an array class, you can't do too much operations directly - reflecting the constructor access to the standard class cannot be used in arrays, and the array does not have any accessible fields, only basic Java. The Lang.object method defines that the array object is used. Special processing of arrays uses a collection of static methods provided by java.lang.Reflect.Array class. The method in this class enables you to create a new array, get the index value of the length, read and write array objects of array objects. Listing 5 shows an effective way to re-adjust the existing array size. It uses reflection to create new arrays of the same type, then copy all data in the old array before returning a new array. Listing 5: extended by a reflective array of code: public Object growArray (Object array, int size) {Class type = array.getClass () getComponentType (); Object grown = Array.newInstance (type, size); System.arraycopy. (Array, 0, Grown, 0, Math.min (Array.getLength (Array), Size); Return Grown;}

Safety and reflection safety during treatment is a more complex problem. Reflecting is often used by the frame type code, because this point, you may want the frame to fully access your code without considering conventional access restrictions. However, in other cases, uncontrolled access will cause serious security risks, such as running 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 reflection and the application of the source code Access: from any location to the access class of the public component, there is no access protected and packaged (default access) component from the private component from the access class of the public component. Finite access is not almost at least some, there is a simple method around these limits. I have extended a normal basic class in the previous example, and a normal basic class - java.lang.Reflect.accessibleObject class. This class defines a setAccessible method that enables you to start or close access detection of instances of one of 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. Listing 6 shows a program, using reflection on one instance of a list 1TWostring class to display security is running: Listing 6: Reflection security is running code: 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 you 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 you do not comment Field.setAccessible (TRUE) code line, then recompile and re-run the code, it will succeed. Finally, if you add JVM parameters to the command line to implement the security manager, it will fail again unless you define the license permission for the ReflectSecurity class. Reflective performance reflection is a powerful tool, but there are also some shortcomings. A main disadvantage is that there is an impact on performance. Using reflection is basically an explanation, you can tell JVM what you want to do and it meets your requirements. This type of operation is always slower than only the same operation directly. In order to explain the performance cost of the reflection, I have prepared a set of reference procedures for this article (see the reference material, complete code link). Listing 7 is a wick 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. Listing 7: Field Access performance test code

Code: public int accessSame (int loops) {m_value = 0; for (int index = 0; index

Code: public int callDirectArgs (int loops) {int value = 0; for (int index = 0; index

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

New Post(0)