[1] The life cycle of the class

 

The life cycle of a java class refers to the whole process of a class file (a file compiled from a java source file) from loading to unloading.

 

table of Contents

1. Load

2. Connect

(1) Verification:

(2) Preparation:

(3) Analysis:

3. Initialization

4. Use

(1) Object instantiation:

(2) Garbage collection:

(3) The end of the object:

5. Class unloading

1. Load

We write a java source file and generate a file with the suffix .class after compilation. This is combined with the four-byte code file, and the java virtual machine recognizes this file. The life cycle of java is the class file from loading to extinction process.

Regarding loading, in fact, the class file of the source file finds the information of the class and loads it into the method area, and then instantiates a java.lang.Class object in the heap area as the entry for the information of this class in the method area.

However, this function is implemented outside the JVM. The main reason is to let the application decide how to obtain this class. The way to implement it in different virtual machines is not necessarily the same. The hotspot virtual machine is loaded when needed. , There are others that are pre-loaded first. (Find and load the binary data of the class)

Class loader:

1. Loader that comes with the Java virtual machine

    a. Root class loader (written in C++, programmers cannot get this class in Java code)

    b. Extension loader, implemented using Java code

    c. System loader (application loader), implemented using Java code

2. User-defined class loader

     Subclass of java.lang.ClassLoader

     Users can customize the way the class is loaded

The class loader does not need to wait for a class to be "actively used for the first time" before loading it. But calling the loadClass method of the ClassLoader class to load a class is not an active use of the class and will not cause the initialization of the class.

 

2. Connect

Generally, it will be interleaved with the loading phase and the initialization phase. The process consists of three parts: verification, preparation and analysis.

(1) Verification :

Determine whether the class conforms to the specifications of the java language, whether there is duplication of attributes and behaviors, and whether the inheritance is reasonable. In short, it is to ensure that the jvm can be executed (to ensure the correctness of the loaded class )

(2) Preparation :

The main thing to do is to allocate memory for the member variables modified by static and set the default initial value ( allocate memory for the static variables of the class and initialize it to the default value )

The default initial values ​​are as follows:

1. The default initial value of the eight basic data types is 0

2. The default initial value of the reference type is null

3. Those with static final modification will be assigned directly, for example: static final int x=10; the default is 10.

(3) Analysis :

The task of this stage is to convert symbol references in the constant pool into direct references . To put it bluntly, JVM will convert all class or interface names, field names, and method names into specific memory addresses . (Convert the symbol reference in the class to a direct reference) . With a direct reference, the referenced target has been loaded into memory .

 

3. Initialization

( Give the correct initial value to the static variable of the class ) and execute it only once

Both the declaration of static variables and the initialization of static code blocks can be regarded as the initialization of static variables. The initialization of static variables and static code blocks of a class is in order. The order is that the class files are initialized from top to bottom. If the parent class has not yet been initialized, then the parent class is initialized first.

This stage is the process of assigning static variables (class variables) and the initialization process of static code blocks, that is, only those modified by static can be initialized . The order of execution is:

The parent class static domain or static code block, and then the subclass static domain or subclass static code block

 

4. Use

There are still three steps in the use of the class: object instantiation, garbage collection, and object termination

(1) Object instantiation :

It is to execute the content of the constructor in the class. If the class has a parent class JVM, the constructor of the parent class will be executed first in a display or implicit manner, open up space in the heap memory for the instance variables of the parent class, and give the default Initial value, and then assign the real value to the instance variable itself according to the code content of the constructor, then open up space for the instance variable of this class, assign the default value, and then assign the value using the constructor. Then, reference the variable to get the first address of the object, and call the instance variable and method by operating the object

(2) Garbage collection :

When the object is no longer referenced, it will be marked with a special garbage mark by the virtual machine (before Java 1.2, the reference counter was used to mark whether garbage collection is required; after 1.2, the root search algorithm is used to determine whether garbage collection is not), Waiting for GC collection in the heap

(3) The end of the object :

After the object is recycled by the GC, the object no longer exists, and the life of the object comes to an end

 

5. Class unloading

That is, the life cycle of the class has reached the last step, and there is no longer a reference to the class in the program, the class will be garbage collected by the JVM, and the life ends ...

Class uninstallation needs to meet the following three conditions at the same time:

1. All instances of this class have been recycled

2. The ClassLoder that loaded this class has been recycled

3. The java.lang.Class object corresponding to this class is not referenced, and there is no way to access this class through reflection anywhere.

The root class loader, extension class loader, and system class loader that JVM comes with, the JVM itself will always reference these class loader, so condition 2 will not be formed. These class loaders will always refer to the class objects they load, so condition 3 will not be formed.

So the only classes that will be unloaded are those loaded by the custom class loader.

example:

class A{

    static int a;//类变量

    String name;

    int id;

    //静态代码块

    static{

        a=10;

        System.out.println("这是父类的静态代码块"+a);

    }

    //构造代码块

    {

        id=11;

        System.out.println("这是父类的构造代码块id:"+id);

    }

    A(){

        System.out.println("这是父类的无参构造函数");

    }

    A(String name){

        System.out.println("这是父类的name"+name);

    }

}

class B extends A{

    String name;

    static int b;

    static{

        b=12;

        System.out.println("这是子类的静态代码块"+b);

    }

     B(String name) {

        super();

        this.name = name;

        System.out.println("这是子类的name:"+name);

    }

}

public class Test666 {

public static void main(String[] args) {

    B bb=new B("GG");

}

}

The output is as follows:

This is the static code block of the parent class 10

This is a static code block of the subclass 12

This is the construction code block id of the parent class: 11

This is the parameterless constructor of the parent class

This is the name of the subclass: GG

 

 

There are two ways to use classes in Java programs:

  (1) Active use

  (2) Passive use

All Java virtual machine implementations must initialize each class or interface "first active use" by the Java program (starting from loading). In other cases, it will not initialize and only perform the steps before initialization .

Only the active use of static inner classes will start the life cycle of the inner classes, and the active use of external classes will only start the life cycle of the outer classes.

Active use:

  ① Create an instance of the class

  ② Access a static variable of a certain class or interface, or assign a value to the static variable

  ③ Call the static method of the class

  ④ Reflection (such as Class.forName("com.alibaba.Test"))

  ⑤ Initialize a subclass of a class

  ⑥ The class that is marked as the startup class when the Java virtual machine is started (Java Test)

 

The initialization steps of the class:

  (1) If a class has not been loaded or connected, then load and connect this class first (not initialized here)

  (2) If the class has a direct parent class, and the parent class has not been initialized, then initialize the direct parent class first

  (3) If there are initialization statements in the class, then directly execute these initialization statements in order

The "active use" of the subclass in the program will cause the parent class to be initialized; but the "active" use of the parent class will not cause the subclass to be initialized (it is impossible to say that generating an object of the Object class will cause all children in the system The class will be initialized)

 

Note: Calling the loadClass method of the ClassLoader class to load a class is not an active use of the class and will not cause the initialization of the class .

  When the java virtual machine to initialize a class, asking it to all of the parent class have been initialized, but this rule does not apply to the interface .

  When a class is initialized, the interfaces it implements are not initialized first.

  When an interface is initialized, its parent interface is not initialized first.

example:

package niuke;

public class TestStaticInitOrder {

    public static void main(String[] args){

        Singleton singleton =  Singleton.getInstance();

        System.out.println("counter1=" +  singleton.counter1);

        System.out.println("counter2=" +  singleton.counter2);

    }

}

class Singleton {

    private static Singleton singleton = new  Singleton();

    

    

    public static int counter1=0;

    

    public static int counter2;

    static{

        counter2 = 0;

    }

    

    private Singleton(){

        counter1++;

        counter2++;

    }

    

    public static Singleton getInstance(){

        return singleton;

    }

}   

Analysis: The program starts to run, first execute the main method, execute the first statement of the main method, call the static method of the Singleton class, here calling the static method of the Singleton class is to actively use the Singleton class. So start to load the Singleton class. In the process of loading the Singleton class, first assign default values ​​to static variables.

  Singleton=null

  counter1 = 0

  counter2 = 0

After assigning the default values ​​to them, what needs to be done is to initialize the static variables and initialize the variables that have been assigned at the time of declaration. As we mentioned above, initialization is assigned from the top to the bottom of the class file. So first assign a value to Singleton, and to assign it, it is necessary to execute its construction method, and then execute counter1++;counter2++; so here counter1 = 1;counter2 = 1; after performing this initialization, first initialize counter1, because counter2 does not Is assigned, so no initialization

At this time: counter1=0;

          counter2=1;

Then after executing the static code block:

        counter1=0;

        counter2=0;

Guess you like

Origin blog.csdn.net/Jack_PJ/article/details/87978585