How to construct the generated at runtime

xiaoxiao2021-03-06  83

SUMMARY: This article shows how categories are scheduled to be constructed when the Java bytecate is displayed by viewing a well-constructed class structure and using the JavaP tool to view the actually generated Java bytecode (bytecode). Keywords: Java Construction JavaP Byte Code Bytecode Follow the Java Specification, the construction of a class instance is followed by: 1. If the constructor (constructor, there is also a translation as a constructor and constructor) is parameter, Parameter binding. 2. Memory Allocation gives a non-static member to the initial value (the value of the original type of member is a specified value, for example the int type is 0, the float type is 0.0F, the Boolean is false; the initial value of the object type is null), static member It is a class object instead of a class instance, so the generation of class instance does not construct or initialize static members, and the generation time of static members will be described later. 3. If there is this () call in the constructor (can be a THIS call) that can be other with parameters, then enter step 6 after the execution is completed, and if there is no THIS call, the next step is performed. 4. Perform an explicit super () call (can be a SUPER () call) or implicit SUPER () call (default constructor), this step has entered a parent class constructor and has been Push to the configuration of the Object object. 5. Execute the members assignment and initialization blocks in the statement. 6. Perform other statements in the construction method.

Now let's take a look at an example of a well-constructed structure: Class Parent {Int PM1; INT PM2 = 10; INT PM3 = Pmethod (); {System.out.Println ("Parent's Instance Initialize Block);} public static int spm1 = 10 ; static {System.out.println ( "Parent's static initialize block");} Parent () {System.out.println ( "Parent's default constructor");} static void staticmethod () {System.out.println ( "Parent's ");} int pmethod () {system.out.println (" parent's method "); return 3;}} class child extends parent {Int cm1; int cm2 = 10; int cm3 = cmethod (); taher co; Public static int scm1 = 10; {System.out.Println ("Child's Instance Initialize Block");} static {system.out.println ("Child's Static Initialize Block";} Child () {co = new other () System.out.Println ("Child's Default Construction");} Child (INT M) {this (); cm1 = m; System.out.Println ("Child's Self-Define Constructor);} static void staticMethod () {System.out.Println ("Child's StaticMethod"); } Int cmethod () {system.out.println ("Child's method"); return 3;}} class other {int}} class Other {Int Om1; other () {system.out.println ("Other's default constructor");}} public class InitializationTest {public static void main (string args []) {child c; system.out.println ("program start"); system.out.println (child.scm1); c = new child (10); system.out .println ("program end");}} Enter this file where the directory is located, then compile this file: Javac InitializationTest.java Run this program: Java? ClassPath. InitializationTest's result is:

program startParent's static initialize blockChild's static initialize block10Parent's methodParent's instance initialize blockParent's default constructorChild's methodChild's instance initialize blockOther's default constructorChild's default constructorChild's self-define constructorprogram end If you have not read the above description about the structure of the class, it is misleading for the construction order class It is the following results (ignoring the default value assignment of parameter binding, memory allocation, and non-static members): 1. Complete the parent class's non-static member initialization assignment and execution of the initialization block (this order depends on the writing of the source file) The order can be placed before the initialization block is preceded, then the first execution will be the initialization block, and this can be verified slightly more.) 2.) 2.) 2. Call the parent class constructor complete the parent class construction. 3. Complete the initialization assignment of non-static members and perform the initialization block. 4. Call the constructor to complete the structure of the object, perform other content in the construction method body. If the order given in the above Java specification can also be reasonably explained the output result of the program, then how can it be seen in the order in the specification instead of the order in which the program is inferred according to the output of the program? Let's use the JDK's own JavaP tool to see the actual order, this tool is a tool for generating a document based on the compiled bytecode, as a tool for generating assembly code according to the machine code Like that.

Anti-compile: javap -c -classpath. The result of Child output is (already marked, alternately using black body and slope): compiled from initializationTest.javaclass child extends parent {int Cm1; int CM2; int CM3; Other Co; Public Static Int SCM1; Static {}; child (); child (int); int cmethod (); static void staticMethod ();} method static {} 0 Bipush 10 2 PutStatic # 22 5 getstatic # 20 8 ldc # 5 10 invokevirtual # 21 13 returnMethod Child () 0 aload_0 1 invokespecial # 14 4 lotfield # 16 10 ALOAD_0 11 ALOAD INT CMETHOD ()> 15 Putfield # 17 18 getStatic # 20 21 ldc # 2 23 invokevirtual # 21 26 aload_0 27 new # 8 30 dup 31 InvokeSpecial # 1 34 Putfield # 19 37 getStatic # 20 40 LDC # 1 42 Invokevirtual # 21 45 returnMethod Child (int) 0 aload_0 1 invokespecial # 12 4 aload_0 5 iLoad_1 6 Putfield # 15 9 getStatic # 20 12 LDC # 4 14 Invokevirtual # 21

17 returnMethod int cmethod () 0 getstatic # 20 3 ldc # 3 5 invokevirtual # 21 8 iconst_3 9 ireturnMethod Void staticmethod () 0 getStatic # 20 3 ldc # 6 5 Invokevirtual # 21 8 Return

Please take a closer to this output and compare the source code. The following explains how to obtain the actual construction order of the class instance according to this output, first explain the format of the output statement before starting the description, the most in front of the statement is the offset value of the instruction, this we can here, The two is the instruction help, which can generally see the instructions from the literal, for example, the GetStatic instruction presses a static member into a data called an operast stack (subsequent instructions can reference the members in this data structure). The structure, and the invokevirtual command is called the Java virtual machine method. The third item is the operand (##, it is actually a tag of the member of the class), some instructions do not have this, because some instructions are in the assembly instruction Some of the instructions are not required (may be an operand to be impunity or not required, this is a feature in Java. If you check the bytecode directly, you will see that the member information is not Direct embedding instruction but stores in a shared pool like all constants used by the Java class, store member information in a constant pool to reduce the size of the byte code instruction, because the instruction only needs to store one of the constant pool The index is not the entire constant, and it is necessary to explain that the order in the constant pool is related to the compiler, so it may not be exactly the same as the output given above in your environment, the fourth item is The previous operand, the actual bytecode is not in the actual bytecode, according to this you can get it well, which member or which method is actually used, which is also the convenience of javap for us. To finish these, you should now easily understand the results above and the content below will be described. Other further information about the Java bytecode, please find your own information. Let's take a look at the beginning of the first part, very like a standard C category, it is true. There is no member statement after the member statement does not initialize the assignment statement and the initialization block. When these statements do? Don't worry first, continue to look down. The second block is a method static {}, comparison to see the first part, it is processed as a static method (can be seen from the previous Method), this is the static initialization block in the source code, from the following statement It is seen that it is the System.out.Println statement, because this method is not the method name, so it cannot be explicitly called, where it will be described later. The third block, the implementation of the default constructor, this is the focus of this article, which is explained in detail below. Since the default constructor in the source code is not explicitly called the THIS method, there is no THIS call (comparison to see the first two sentences of the construction method of the next piece), and there is no explicit super call, then implicit Call the default constructor of the parent class, that is, the first two statements (mainly statement invokespecial # 14 ) C? classpath. Parent anti-compilation of the bytecode of the parent class to see the construction process of this class); followed by the first initialization assignment statement cm2 = 10 (i.e., the next three statements, mainly Bipush 10 and Putfield # 15 answered questions in the first block, that is, initializing assignment statements to where.

); Next is to execute cm3 = cmethod () (next four statements); then perform the contents in the initialization block System.out.Println ("Child's Instance Initialize Block" (next three statements); Java specification The internal agreed content is performed, and the contents of the method of constructing the construction method are started, that is, CO = new other () (next five statements) and system.out.println ("Child's Default Construction") (next Three statements), the last method is executed, and the last method returns (the last statement return). The rest of the cases should not be explained, there should be, there is a refined constructor to call the non-arranging structure and then perform its own method body, and the member method CMethod executes a print statement and returns a constant 3, and the static method StaticMethod executes a phrase statement. In addition, you need to explain that you can call the THIS in the reference method, then look at the results of the anti-compilation, you will find that two constructors are very similar, if you change the contents of the two constructors to the same Then, the anti-compilation generation will also be the same. From this, the judgment of the THIS call in the constructor can be explained in the description of the constructor starting in this article is completed in the compilation phase, not at the operation phase (meaning in the description, which is this judgment is running at runtime). Another detail of the construction process You may not believe that the second in the order is the default initial value of non-static members (the memory allocation section cannot be adopted, this is the Java virtual machine is automatically completed), this you can The value of the CM3 is printed by using System.out.Println (CM3) by the start of the CMethod method of the subclass Child (output to 0, and the value of other type members can be obtained by a similar method). Let's talk about another problem that has not been resolved: Static member initialization and static initialization block do not complete? This can be inferred by a small trial: Yes when using this type object for the first time (note is a class object rather than class instance, for the public static member of the class, it can be accessed directly through the class name, do not need Generate a class instance, this is the use of a class object instead of the use of class instances, if such objects are not used before generating the first class instance, then the construction of the class object before constructing the first class instance (Ie, the static member initialization and perform a static initialization block), then execute the configuration process of the above instance), the steps of the test are as follows: 1. Modify the main method, will use the system.out.println (child.scm1) and C = New child (10) Note (do not delete, you also need to use these two statements), compile the running program, the output will only have Program Start and Program End, this shows that there is no use class object does not generate class instances The construction of a static member. 2. Cancel the Note of System.out.Println (Child.scm1), and outputs the execution output of the static initial block portion of the parent class and subclass after compiling operation (using subclass of class objects will result in a class that generates parent class. Objects, parent classes are constructed in subclass).

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

New Post(0)