Connection and initialization of the Java reflection class [reprint]

Source: Internet
Author: User
Tags instance method

  Java virtual machines are loaded, concatenated, initialized to make a Java type available to Java programs , as shown in which the connection process is divided into three parts: validation, preparation, parsing . The parsing process of some of these classes can be deferred until the program actually uses one of its symbolic references to parse.

The parsing process can be deferred until the initialization of the class, but this is conditional, and the Java Virtual machine must be initialized when each class or interface is actively used.
The following are active use cases:
(1). Create a new instance of a class, whether created directly from new or by reflection, cloning, serialization
(2). Using static methods of a class
(3). Access static fields for a class or interface
(4). Call some of the reflection methods in Javaapi
(5). Initializes a subclass of a class (requiring its ancestor classes to be initialized, otherwise it cannot properly access its inherited members)
(6). Start a class marked as a startup class (with the main () method)
Active use causes the class to initialize, and its superclass is initialized before the class is initialized, but when a child class accesses a static field or method of the parent class, the access is passive access for the subclass (or subinterface, the implementation class of the interface), or the Class (interface) that is not in the class (interface). Static members declared in the.
Such as:
Grandpa is defined as follows:

1 Package com.ice.passiveaccess;2 3 public class Grandpa {4     static{5         System.out.println ("Grandpa was Initialized. "); 6     }7}

The parent is defined as follows:

1 Package com.ice.passiveaccess;2 3 public class Parent extends grandpa{4     static String language = "Chinese"; 5     STA Tic{6         System.out.println ("Parent was initialized."); 7     }8}

Cindy is defined as follows:

1 Package com.ice.passiveaccess;2 3 public class Cindy extends parent{4     static{5         System.out.println ("Child is Initialized. "); 6     }7}

Language members of the parent class are now accessed through Cindy

1 Package com.ice.passiveaccess;2 3 public class Passiveaccesstest {4 public     static void Main (String args[]) {5         System.out.println (cindy.language); 6     }7}

The results are as follows:

This is a passive access, Cindy itself is not initialized

The following is a brief description of the loading, validation, and initialization process:
1. Loading:
(1). Locate the class file of that type, producing a class file of that type binary data stream (the loadClassData () method that ClassLoader needs to implement)
(2). Parse the binary data stream into a data structure within the method area
(3). Create a Java.lang.Class instance of this type
As you can see in the relevant code of the loader, a Java type Object (class object) is eventually created by DefineClass ().
2. Verify that:
The class file validator requires four separate scans to complete the verification work, where:
The first scan is carried out at load time, and the class file is checked for structure, such as
(1). Check the magic number to determine if the file is a normal class file
(2). Check the primary and secondary version number to determine if the class file is compatible with the Java Virtual machine
(3). Check the length and type of the class file to avoid any missing or appended contents of the class file.
The second scan is performed during the connection process, and the type data is checked for semantics, primarily to check the binary compatibility of each class (primarily to see the relationship between the superclass and subclasses) and whether the class itself conforms to a particular semantic condition
(1). The final class cannot have subclasses
(2). The final method cannot be overridden (overwritten)
(3). There is no incompatible method declaration between subclasses and superclass
(4). Check that the constant pool entry type is consistent (for example, if the contents of the Constant_class constant pool point to a Constant_utf8 string constant pool)
(5). Check all the special strings of the constant pool to determine whether they are instances of the type they belong to, and whether they conform to a specific context-independent syntax, format
The third scan is a bytecode verification, its verification content and implementation is more complex, the main check whether the bytecode can be implemented securely by the Java virtual machine.
The four-pass scan is performed during the parsing process to validate the symbol reference. During a dynamic connection, when you look up a referenced class, interface, field, or method by holding a symbolic reference to a constant pool, when you replace the symbol reference with a direct reference, you first need to confirm that the found element really exists, and then you need to check the access permission, whether the element being found is a static class member, not an instance member.
3. Prepare:
Allocates memory for class variables, sets default initial values (memory setting initial values, rather than really initializing class variables, i.e. declaring int i = 5 in a class, but actually allocating memory and setting the initial value to 0)
4. Analysis:
Look for the symbol references for classes, interfaces, fields, methods in the constant pool of the class, and replace those symbol references with direct references
5. Initialize:
Assigns the specified initial value to the class variable (at this time the int i = 5 must be given an initial of 5). This initial value is given in two ways, one is through the initialization of the class variable, and the other is the static initialization statement. These initialization statements are placed in the method together with the Java compiler.
As mentioned earlier, the initialization of a class requires initializing its immediate superclass and recursively initializing its ancestor class, which is done by invoking the initialization method of the class. In addition, for an interface, it is not necessary to initialize its parent interface, but only the interface initialization method of the interface is performed.
Attention:
(1). During the initialization phase, only the class variables (static global variables) are initialized, and when the class variable is declared as a final type, the tangent initialization statement takes a constant expression to initialize the assignment, and it is not initialized, it will be evaluated directly by the compiler and saved in the constant pool. The use of these variables will also embed their variable values directly into the bytecode.
such as the Usefulparameter class are as follows:

Class-area-class variables are initialized as follows:

In area < clinit>, 2 and 4 will be embedded directly into the bytecode.

(2). The initialization of the interface differs from the class, and in the initialization phase, all public, static, and final types declared in the interface, fields that cannot be compiled as constants are initialized.
6. Class instantiation
Here you need to understand what class initialization is, what is class instantiation, and the initialization of an instance object of a class
As mentioned earlier, class (static) variables are assigned initial values when classes are initialized, class initialization can access static fields and methods of the class, and access to non-static (instance) fields and methods of the class requires the creation of an object instance of the class, so that the instantiation of the class is after the initialization of the class, and the object of that class is created on the heap.
The static methods and fields of a class belong to a class, as the type data is stored in the method area, its life cycle depends on the class, and the instance method and field are in the Java heap, whose life cycle depends on the life cycle of the object.
classes are initialized from ancestor classes to subclasses, in order of occurrence, initialization statements for class variables, static initialization statement blocks, and so on. The initialization of class instances is similar to initialization of class members, initialization statements, instance initialization blocks, and construction methods from ancestor classes to subclasses, in order of occurrence.
Like what:

1 package com.ice.init; 2  3 public class Parent {4 public     static int i = print ("Parent static:i"), 5 public     int II = print ("Parent:ii "); 6  7     static{8         print ("Static initialization of Parent class"), 9     }10         ("Parent class initialization");     }14     Parent (String str) {         System.out.println ("Parent constructor:" + str);}18 public     static int print (String str)         { System.out.println ("initial:" + str);         return i;22     }23}

The subclass child is as follows:

1 package com.ice.init; 2  3 public class child extends parent{4 public     static int i = print ("Child Static:i"), 5 public     int II = Prin T ("Child:ii"); 6  7     static{8         print ("Subclass static Initialization"), 9     }10         ("subclass instance Initialization");     }14     Child (String str) {         System.out.println (str);         +-("Child constructor:" + str);     }19     public static int print (String str) {         System.out.println ("initial:" + str);         return i;23     }24     public static void Main (String args[]) {The child of child         = new Child ("Cindy");     }28}

The order of initialization is:

The Java compiler generates at least one instance initialization method < init for each class, and a < init > method is divided into three parts: another initialization method < init > (), byte code initialized for any instance member, Byte code of the method body of the method of construction
The < init > method is called as follows:
If < init > indicates that another constructor method is explicitly called from the This () method, then another constructor is called, otherwise, if the class has a direct superclass, if < init > indicates that the constructor of its superclass is explicitly called from the Super () method, The constructor of the superclass is called, otherwise the parameterless construction method of the superclass is called by default. In this way, the initialization of the corresponding instance member is done from its ancestor class to that class, respectively (possibly quilt overrides)


Next, end this section with a question:
Judging output:

1 package com.ice.init; 2  3 class T  implements cloneable{4 public       static int k = 0, 5 public       static T t1 = new T ("T1"); 6       Pub Lic static T t2 = new T ("T2"); 7 public       static int i = print ("i"), 8 public       static int n = 9, public       int j = Print ("J");           Print ("Construction block"),       }14 static       {           print ("static block");       }18 public       T (String str) {           System.out.println ((++k) + ":" + str + "    i=" + i + "  n=" + N);           ++n; + + i;22       }23 public       static int print (String str) {           System.out.println (++k) + ":" + str + "   i=" + I  + "   n=" + N);           ++n;27           return + + i;28       }29 public       static void Main (string[] args) {           T = New T ("Init");       }33     }
题解如下:
(1). First the T class is loaded, initialized after the connection, and the fields K, T1, T2, I, n, and static blocks are initialized first. (2). The initialization of the T1 instance initializes the instance member J, which actually initializes the content of the parent class first, calls the static method print and executes the instance initialization block {}, Output: 1:j i=0 n= 0 (i and n are not initialized) 2: Construction Block I=1 n=1 (3) then call T1 Example of the constructor, output: 3:t1 i=2 n=2 (4). Similar to the initialization of a T2 instance: 4:j i=3 n= 3 5: Construction block i=4 n=4 6:t2 i=5 n=5 (5). Initialization of I: 7.i i=6 n=6 (6). Initialization and Static of n Block initialization: 8. Static block i=7 n=99 (n already initialized) (7). T instance initialization: 9.J i=8 n= 100 10. Construction block i=9 n= 101 11.init i=10 n= 102

Connection and initialization of the Java reflection class [reprint]

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.