About static blocks in Java

Class loading characteristics and timing

Before introducing static, you can take a look at the relevant classes

Class Loading Features

Each class is loaded only once during the lifetime of the JVM.

The principle of class loading: lazy loading, load as little as possible, because the space of the virtual machine is limited.

when the class is loaded

1) The first time an object is created, the class needs to be loaded.

2) Classes are loaded when static methods are called, and classes are loaded when static properties are accessed.

3) When loading a subclass, the parent class must be loaded first.

4) Creating an object reference does not load the class.

5) When the subclass calls the static method of the parent class

(1)当子类没有覆盖父类的静态方法时,只加载父类,不加载子类

(2)当子类有覆盖父类的静态方法时,既加载父类,又加载子类

6) To access static constants, if the compiler can calculate the value of the constant, the class will not be loaded, for example: otherwise the public static final int a =123;class will be loaded, for example:public static final int a = math.PI。

Three common places of static

  1. Modified member variables
  2. Decorate member methods
  3. static block

Here is a brief introduction to the method of modifying members, and the following will continue to introduce static blocks

It is the same concept as C++. But in the JVM, the JVM will also divide a tentatively called static storage area for storing method definitions. In fact, from a larger perspective, it stores the definitions of various classes. When we generate objects through new, objects will be created according to the definitions of the classes defined here.

Let's observe the output results of the two pieces of code, the difference between adding static and not adding static:

public class Person {
    
    
    String name;
 
    int age;
    
    public String toString() {
    
    
        return "Name:" + name + ", Age:" + age;
    }
    
    public static void main(String[] args) {
    
    
        Person p1 = new Person();
        p1.name = "zhangsan";
        p1.age = 10;
        Person p2 = new Person();
        p2.name = "lisi";
        p2.age = 12;
        System.out.println(p1);
        System.out.println(p2);
    }
 
    /**输出结果
     * Name:zhangsan, Age:10
     * Name:lisi, Age:12
     */
}
public class Person {
    
    
    String name;
    // 给age加上static
    static int age;
    /* 其余代码不变... */
 
    /**输出结果
     * Name:zhangsan, Age:12
     * Name:lisi, Age:12
     */
}

Observing the conclusion of the output results: Through running the results, you can see that the age is 12, and only the last value assigned to age is saved. Why is this, what happened in memory?
insert image description here
After adding the static keyword to the age attribute, the Person object no longer has the age attribute, and the age attribute will be handed over to the Person class for management, that is, multiple Person objects will only correspond to one age attribute. If you make a change, other objects will be affected.

What is a static block?

**Static code block: **The execution priority is higher than that of non-static initialization blocks. It will be executed once when the class is initialized, and it will be destroyed after execution. It can only initialize class variables, that is, static modified data members.

features

Executed as the class is loaded, and only once

wording

static{

}

Correspondingly, look at the non-static code block
Non-static code block: If there is a static initialization block during execution, the static initialization block is executed first and then the non-static initialization block is executed. It will be executed once when each object is generated, and it can initialize the instance of the class variable. Non-static initialization blocks are executed when the constructor is executed, before the body of the constructor is executed.
The writing method of non-static code block:
{

}

static block static

(1) The static keyword also has a more critical role, which is used to form static code blocks ( static{}ie static blocks) to optimize program performance.
(2) The static block can be placed anywhere in the class, and there can be multiple static blocks in the class.
(3) Executed when the class is first loaded and will only be executed once ( this is the reason for optimizing performance!!! ), each static block will be executed in the order of the static block, generally used to initialize static variables and call static method.

The following two pieces of code illustrate why static{} can optimize program performance.

Example:

/**
 * 每次调用isBornBoomer的时候
 * 都会生成startDate和birthDate两个对象,造成了空间浪费
 */
class Person{
    
    
    private Date birthDate;
     
    public Person(Date birthDate) {
    
    
        this.birthDate = birthDate;
    }
     
    boolean isBornBoomer() {
    
    
        Date startDate = Date.valueOf("1997");
        Date endDate = Date.valueOf("2019");
        return birthDate.compareTo(startDate)>=0 && birthDate.compareTo(endDate) < 0;
    }
}
/**
 * 这里使用了static块
 * 只需要进行一次的初始化操作
 * 节省内存空间,优化性能
 */
class Person{
    
    
    private Date birthDate;
    private static Date startDate,endDate;
 
    static{
    
    
        startDate = Date.valueOf("1997");
        endDate = Date.valueOf("2019");
    }
     
    public Person(Date birthDate) {
    
    
        this.birthDate = birthDate;
    }
     
    boolean isBornBoomer() {
    
    
        return birthDate.compareTo(startDate)>=0 && birthDate.compareTo(endDate) < 0;
    }
}

how to use?

Just define a static code block in the class, and then write the corresponding code in it

Little knowledge points
The execution order of static code blocks: static code block -----> non-static code block --------> constructor

In the interview, it may appear together with other knowledge points.
For example, it may appear together with inheritance knowledge points.
Example:
parent class:

public class Fathers {
    
    
    static{
    
    
        System.out.println("父类中的静态代码块");
    }
    Fathers(){
    
    
        System.out.println("父类中的构造函数");
    }

    {
    
    
        System.out.println("父类中的非静态代码块");
    }

    public static void main(String[] args) {
    
    
        System.out.println("父类中的main方法");
    }
}

Subclass

public class Sons extends Fathers{
    
    
    static {
    
    
        System.out.println("子类中的静态代码块");
    }
    Sons(){
    
    
        System.out.println("子类中的构造方法");
    }
    {
    
    
        System.out.println("子类中的非静态代码块");
    }

    public static void main(String[] args) {
    
    
        System.out.println("子类中的main方法");
        new Sons();
    }
}

Output after executing the main method in the subclass
insert image description here

If you want to see the characteristics of the static code block, it is executed as the class is loaded, and it is executed only once, you can see it by adding a new subclass in the parent class.
Execute the main method in the parent class this time:
insert image description here
Then compare it with the result of the new sons class in the subclass above. The following picture shows the main method executed by the parent class, and the picture above shows the main method executed by the subclass.

It can be seen that the main method was originally executed in the subclass. Since the subclass inherits the parent class, the static code block in the parent class is executed first.

But in the figure below, the main method is executed in the parent class. The parent class itself executes the main method and executes a static code block once, but in the parent class, the main method is a new subclass. According to the inheritance relationship, the parent class The static code block should still be executed, but it is not printed in the console . This is due to the characteristics of the static code block. It is executed as the class is loaded, and it is only executed once.
insert image description here

Reference article (invasion and deletion):
Static block in Java (static{})
Java static keyword and static{} statement block
Detailed explanation of static code block in java

Guess you like

Origin blog.csdn.net/mfysss/article/details/129245582