How exactly is the Java class loaded and initialized?

Source: Internet
Author: User
Tags class definition export class

How does a Java Virtual machine load a compiled. class file into a virtual machine? How do I initialize a class after loading? Is the initialization process for static class variables and instance class variables the same, and how are they initialized? This article will

is to solve the above 3 problems.

If there is a wrong place, please understand and welcome all of you can give criticism, thank you in advance.

1. Java Virtual machine load. class process

The virtual machine loads the class file into memory, then verifies, parses, and initializes, eventually forming the Java type, which is the load-carrying mechanism of the virtual machine. Load, validate, prepare, initialize the sequence of these 5 stages is determined,

The loading process of a class must begin in this order. These phases are usually cross-intersecting and mixed. In some cases, the parsing phase can begin after the initialization phase---in order to support runtime bindings for the Java language.

In the Java Virtual Machine specification, there is no mandatory constraint on when to start loading, but there are strict rules that must be initialized (load, verify, prepare to start before initialization):

1) encounters new, Getstatic, Putstatic, or invokestatic 4 bytecode directives, triggering initialization if no class has been initialized.

2) The method of using the Java.lang.reflect package, in the event of a reflection call, if there is no initialization, the first trigger initialization

3) When initializing a class, the initialization of the parent class is triggered first if it is found that the parent class is not initialized

2. Load, verify, parse

Loading is to get the binary byte stream of this class by specifying the fully qualified name of the class, and then flow the binary bytes into the data structure of the method area, generating a class object in memory that represents it. Verification is to ensure

The byte stream in the guaranteed class file conforms to the requirements of the virtual machine and does not compromise the security of the virtual machine. The loading and validation phases are easier to understand, and there is no longer much to explain. The parsing phase is special and the parsing phase is the virtual machine

The process of converting a symbol reference in a constant pool to a direct reference. If you want to understand the process of parsing, you must first understand some of the class file information. class file uses a pseudo-structure of a C-like struct to store our

Various information about the Java class of the code. The constant pool (Constant_pool) in the class file is a table-like repository that stores the fully qualified name of the class and interface of the Java class we write, the name and descriptor of the field,

The name and descriptor of the method. After the Java virtual machine loads the class file into the virtual machine memory, the constant pool information and other data in the class file are saved to the method area of the Java Virtual Machine memory. We know the class file

The constant pool holds the full name of the Java class, the full name of the interface and the field name descriptor, the name and descriptor of the method, and the data that is loaded into the method area of the JVM's memory, which is called a symbolic reference. And putting these classes of

The process of fully qualified names, method descriptors, etc., which the JVM can obtain directly from the JVM memory address, pointers, etc., is parsing. The virtual machine implementation can cache the results of the first parse and avoid repeated execution of parsing actions.

When parsing the fully qualified name of a class, assuming that the current class is D, if you want to parse a never-parsed symbol reference n into a direct reference to a class or interface C, the concrete way to do this is to take the virtual opportunity to represent N

The fully qualified name is passed to the class loader D to load the Class C. This block may not be very well understood, but we can directly understand to call the class D ClassLoader to load N, and then complete the n--->c parsing, you can.

3. Preparation phase

The reason for the preparation phase in front of the parsing phase, after getting to the parsing phase, is that the preparation phase has involved initialization of class data assignment. It has something to do with the initialization we're talking about here, so we're going to get this.

Described After the Java virtual machine loads the class file and validates it, it formally allocates memory to the class variable and sets the initial value of the class variable. The memory used by these variables will be allocated in the method area. Note that this is the class variable,

The static modifier modifies the variable, and at this point the memory allocation is started, and the initial value is set. For example, in the sentence of public static int value = 123, when the preparation phase is executed, the value

Allocate memory and set the initial value of 0 instead of the 123 we imagined. So when will we assign the 123 we write to value? Is the initialization phase we're going to talk about here.

4. Initialization phase

The class initialization phase is the final stage of the class loading process. At this stage, the Java Virtual machine really starts executing the Java program code in the class definition. How does a Java Virtual machine complete initialization? This starts with the compilation. Preparing

When translating, the compiler automatically collects statements from all static variables (class variables) and static statement blocks (static{} blocks) in the class, and the compiler collects the order based on the order of the statements in the Java code.

After the collection is completed, the Java class's static{} method is compiled, and the Java Virtual machine guarantees that the static{} method of a class executes correctly in a multithreaded or single-threaded environment and executes only once. In the course of execution, the end

The initialization of the class variable. It is worth noting that if we do not explicitly declare static{} blocks in our Java class, if there are static variables in the class, the compiler will default to us to generate a static{} method. We can pass

Javap-c's command, take a look at the static{} method that the compiler generated or merged for us in Java bytecode:

public class Staticvalinittest {public    static int value = 123;}

What we're talking about is a single-class case, what if there's inheritance? If there is inheritance, how is the class variable in the parent class initialized? This is resolved by the virtual machine: the virtual opportunity guarantees that the static{} method of the subclass executes

Before, the static{} method of the parent class has been executed. Because the static{} method of the parent class executes first, it means that the static variable of the parent class takes precedence over the static variable assignment operation of the child class.

The above is all static variables, how to solve the instance variables? The initialization of an instance variable is, in fact, similar to the process of a static variable, but time and place are different. Let's take the following dog class as an example.

public class ' Dog ' {public    String type = ' Tai di ';    public int age = 3;}

1) When creating an object with new dog (), first allocate enough space on the heap for the Dog object.

2) This storage space is zeroed out, which is to automatically set all the basic types of data in the dog object to default values, whereas reference types are set to null (a process similar to the preparation phase of a static Class)

3) Java collects our instance variable assignment statements, which are combined to execute an assignment statement in the constructor. Without constructors, the system will default to us to generate constructors.

At this point, the theoretical basis for the initialization of Java classes has been completed, and most of the theories and ideas are derived from the "deep understanding of Java Virtual Machine" book. With the above theoretical basis,

In the case of complex class initialization, we can deal with it, let's take an example to make a specific analysis.

public class Insect {    private int i = 9;    protected int J;        protected static int x1 = Printinit ("Static insect.x1 initialized");        Insect () {        System.out.println ("base class constructor Stage: i =" + i + ", j =" + J ");        j = n;    }        static int Printinit (String s) {        System.out.println (s);        return;}    } public class Beetle extends insect {        protected int k = Printinit ("beetle.k initialized");        protected static int x2 = Printinit ("Static beetle.x2 initialized");            public static void Main (string[] args) {                Beetle b = new Beetle ();}    }

The above example comes from the Java programming idea, what is the execution result of the above code? If we understand the theory above, it is easy to know that the result is:

Static insect.x1 initialized

Static beetle.x2 initialized

Base class constructor Stage: i = 9, j = 0

BEETLE.K initialized

The specific execution result process is:

When executing the main method of the Beetle class, because the main method is a static method, as we know above, when executing the static method of the class, if the class is not initialized, it is initialized,

Therefore, when we execute the main method, we execute the load-validate-prepare-parse---Initialize the process. In the final initialization, there is another constraint: the virtual opportunity is guaranteed to be in the subclass of static{}

The static{} method of the parent class has been executed before the method executes. Therefore, after parsing is performed, the initialization of the parent class is performed first, and when the parent class is initialized,

Output: Static insect.x1 initialized

Then initialize the subclass, output: static beetle.x2 initialized

The above two lines of output, is the initialization of static variables, is the first time to call the static method, that is, in the execution of new, getstatic, putstatic, or invokestatic the 4 bytecode instruction when the trigger. So

If you put Beetle B = new Beetle () in the static Main method in the above example;

Comment out, the above two lines will still be output. Then there is the execution of Beetle B = new Beetle (); We know that the constructor of the parent class is automatically called when the subclass object is instantiated.

So, then the output: the base class constructor stage: i = 9, j = 0

The next step is to execute its own constructor, create the class instance object on the heap, zero the instance object space, and then execute the assignment statement k = Printinit ("beetle.k initialized");

Output: BEETLE.K initialized

At this point, the entire class loading and initialization is complete, it is not easy to understand, while winning chase, we still look at an example:

public class Base {    Base () {        preprocess ();    }    void Preprocess () {    }}public class Derived extends Base {public    String whenamiset = ' Set when declared ';     @Override     void Preprocess () {        Whenamiset = "set in Preprocess";    }        public static void Main (string[] args) {        Derived d = new Derived ();        System.out.println (D.whenamiset);    }}

This example source and @ Left ear mouse's blog, I just read his blog in this example, just remembered to write an article in order to straighten out the Java class initialization process, only this blog. Nonsense not much to say that this example inside that there is

A place to compare around: when the parent class executes the constructor, called the subclass (export Class) overloaded methods, in the subclass of overloaded methods, the instance variable is given a value, it is this assignment that interferes with our class initial

and understanding.

We don't care what the class does, and we analyze it as we did in the previous example:

1. When executing the derived class static Main method, the class variable initialization is performed, but the parent class and subclass in this example do not have a class variable, so this step does nothing and initializes the instance variable.

2. When you execute new Derived (), the constructor of the parent class is called, because of the overloads of the subclass, the Preprocess method of the subclass is called, and the instance variable Whenamiset is assigned a value of "set in Preprocess"

3. Then execute the subclass derived constructor, in the constructor, there is a compiler for us to collect the generated instance variable assignment statement, and finally, the instance variable Whenamiset assigned to "set when declared"

4. So the final output is: set when declared

If you do not understand this, you can add comments to the derived class, change to the following look, output to see, is not the implementation process clearer?

public class Derived extends Base {        //prep Stage Assignment Whenamiset=null public    String whenamiset = "set when declared";        Public Derived () {        System.out.println ("Do son constructor");    }         @Override     void Preprocess () {        System.out.println ("Do son process");        System.out.println ("Whenamiset:" + whenamiset);        Whenamiset = "set in Preprocess";        System.out.println ("Whenamiset:" + whenamiset);        System.out.println ("Set in Preprocess End");    }    public static void Main (string[] args) {        Derived d = new Derived ();        System.out.println (D.whenamiset);    }}    

Resources:

"In-depth understanding of Java virtual machines"

The idea of Java programming

Http://coolshell.cn/articles/1106.html

Look at the blog when you do not feel anything, write a blog when you know also to organize the language, but also to typesetting God horse, so also want to reprint when can give a

Http://www.cnblogs.com/jimxz/p/3974939.html

Link description, Thank you

Initialization Order of Java classes

For static variables, static initialization blocks, variables, initialization blocks, constructors, they are initialized sequentially (static variables, static initialization blocks) > (variables, initialization blocks) > constructors
。 We can also verify this with the following test code:

public class Initialordertest {
static variables
public static String Staticfield = "static variable";
Variable
Public String field = "Variable";
Static initialization blocks
static {
System.out.println (Staticfield);
SYSTEM.OUT.PRINTLN ("Static initialization Block");
}
Initialize block
{
System.out.println (field);
System.out.println ("initialization block");
}
Constructors
Public Initialordertest () {
System.out.println ("constructor");
}
public static void Main (string[] args) {
New Initialordertest ();
}
}
Running the above code, we will get the following output result:
1. Static variables
2. Static initialization block
3. Variables
4. Initializing blocks
5. Constructors

(go) How exactly is the Java class loaded and initialized?

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.