Статические статические блоки кода и порядок выполнения между блоками кода

Java

предисловие В Java порядок выполнения блоков статического кода, конструктивных блоков кода, обычных блоков кода и функций-конструкторов является основой, которую должен освоить изучающий Java. Цель этого блога — дать каждому понять порядок выполнения между ними.

Классификация кодовых блоков

В основном существует три типа кодовых блоков: статические кодовые блоки, конструктивные кодовые блоки и обычные кодовые блоки.

порядок выполнения блока кодаСтатический кодовый блок -> Конструкторский кодовый блок -> Конструктор -> Обычный кодовый блок

Порядок выполнения блоков кода в наследовании:Статический блок родительского класса -> статический блок дочернего класса -> блок кода родительского класса -> конструктор родительского класса -> блок кода дочернего класса -> конструктор дочернего класса

1. Статический блок кода (также называемый статическим блоком, статическим блоком инициализации)

Код в блоке статического кода Java запускается при загрузке класса в JVM и выполняется только один раз, что означает, что код можно вызывать без создания экземпляра класса. В общем, если какой-то код должен быть выполнен при запуске проекта, вам нужно использовать статические блоки кода, поэтому статические блоки часто используются для инициализации свойств класса!

Пять пунктов о статических блоках статического кода

1. Код в блоке статического кода Java будет выполняться, когда класс загружает JVM, и будет выполняться только один раз. 2. Статические блоки часто используются для выполнения инициализации свойств класса. 3. Статические блоки имеют приоритет перед различными блоками кода и конструкторами.Если в классе несколько блоков статического кода, они будут выполняться в том порядке, в котором они написаны. 4. Блоки статического кода могут быть определены в любом месте класса, кроме тела метода [тело метода здесь — любое тело метода] 5. Статические блоки кода не могут получить доступ к обычным переменным

Причина, по которой статический блок кода, описанный в 4, не может существовать ни в одном теле метода, на самом деле очень проста, потому что общий метод заключается в загрузке класса, а затем создании экземпляра объекта с помощью new, и метод может быть запущен через объект, в то время как блоку статического кода нужно только загрузить класс. Тогда он будет работать. Для статических методов, когда класс загружается, статический метод также загружается, но мы должны получить к нему доступ через имя класса или имя объекта, то есть, по сравнению со статическими блоками кода, статические блоки кода запускаются по собственной инициативе. , а статические методы вызываются пассивно.Независимо от метода, мы должны четко указать, что наличие статического блока кода будет запускаться автоматически при загрузке класса., и независимо от того, находится ли он в обычном или статическом методе, он не может запускаться автоматически.

По той же простой причине, что статические блоки кода не могут получить доступ к обычным переменным, как описано в 5. Обычные переменные вызываются объектами-экземплярами, а их объекты-экземпляры не существуют в статических блоках кода Как мы можем вызывать переменные?

Формат использования блока статического кода

static{
  ..............
}

2. Блок кода построения (также называемый блоком инициализации построения)

Когда вы услышите название, вы поймете, что оно неотделимо от метода строительства! Да, но он все же принципиально отличается от метода построения.Все мы знаем, что методов построения может быть много в каждом методе.Каждый раз при создании объекта выполняется его метод построения, а один метод построения может создать N объектов. метод построения Он более «холодный», а блок кода построения более «собачий». Пока класс создает экземпляр объекта, код построения выполняется один раз, и функция блока кода построения вызывается каждый раз заранее. объект создается, поэтому он может выполнять функцию подсчета количества созданий объекта. Конечно, создание блоков кода происходит относительно редко!

Составление сводки блока кода:

1. Блок кода построения вызывается при создании объекта и вызывается один раз при каждом создании объекта 2. Блок строительного кода выполняется вместо конструктора, и работа блока строительного кода зависит от конструктора. 3.Блок кода конструкции определен в классе

Для "в 2полагаться"Можно понять, что если объект не инстанцирован (то есть не выполнен конструктор), то блок кода конструкции выполняться не будет!

3. Кодовый блок (также называемый обычным кодовым блоком, блоком инициализации)

Сводка блока кода

1. Обычные блоки кода определяются в теле метода. 2. Форматы обычных кодовых блоков и строительных кодовых блоков одинаковы.{}3. Единственная разница, которую можно непосредственно увидеть между обычными кодовыми блоками и конструкционными кодовыми блоками, заключается в следующем.Конструктивные блоки кода определяются в классах, а обычные блоки кода определяются в телах методов.

Выполнение последовательных тестов кода

Выше было сказано почти, давайте начнем код!

package com.gx.initializationblock;

public class Initializationblock {

    int intA;
    int intB;


    public Initializationblock() {
        System.out.println("无参构造器00000000");
    }

    public Initializationblock(int a) {
        System.out.println("一个参数的构造器");
        
    }


    {
        intA = 10;
        intB = 15;

        System.out.println("构造初始化块11111");
    }

    {
        System.out.println("构造初始化块22222");
    }

    {
    	
        System.out.println("构造初始化块33333");
    }

    //静态初始化块
    static {
        System.out.println("静态初始化块01010101");
    }

    static {
        System.out.println("静态初始化块0202020202");
    }
    public void method(){
    	{
    		System.out.println("普通初始化块");
    	}
    }
}

тестовая демонстрация

package com.gx.initializationblock;

/* 初始化块一
	 * 因为静态块是在类的初始化阶段完成的,
	 * 因此在创建某个类的第二个对象时,该类的静态块就不会执行了
	 * 
	 * 在单个类中,静态初始化块,初始化块,构造器
	 * 多个类的继承中初始化块、静态初始化块、构造器的执行顺序
在继承中,先后执行父类A的静态块,父类B的静态块,最后子类的静态块,然后再执行父类A的非静态块和构造器,然后是B类的非静态块和构造器,最后执行子类的非静态块和构造器
 */
public class Demo1 {
    public static void main(String[] args) {
        Initializationblock initializationblock = new Initializationblock();
        initializationblock.method();
        System.out.println("------------");
        //多打印几个对象的目的是:好看出Static静态代码块只执行一次!!!
        Initializationblock initializationblock2 = new Initializationblock(); //因为静态块是在类的初始化阶段完成的,因此在创建某个类的第二个对象时,该类的静态块就不会执行了
        initializationblock2.method();
        Initializationblock initializationblock3 = new Initializationblock();
        initializationblock3.method();
    }
}

распечатать результат

静态初始化块01010101
静态初始化块0202020202
构造初始化块11111
构造初始化块22222
构造初始化块33333
无参构造器00000000
普通初始化块
------------
构造初始化块11111
构造初始化块22222
构造初始化块33333
无参构造器00000000
普通初始化块
构造初始化块11111
构造初始化块22222
构造初始化块33333
无参构造器00000000
普通初始化块

Заключение: порядок исполненияСтатические блоки кода > Конструктивные блоки кода > Конструкторы > Обычные блоки кода

Порядок выполнения блоков кода в наследовании

Ничего не говорите, просто напишите код напрямую: отношения наследованияBaseThree --> BaseTwo --> BaseOneКласс BaseOne

package com.gx.initializationblock;

public class BaseOne {

    public BaseOne() {
        System.out.println("BaseOne构造器");
    }

    {
        System.out.println("BaseOne初始化块");
        System.out.println();
    }

    static {
        System.out.println("BaseOne静态初始化块");

    }

}

Класс BaseTwo

package com.gx.initializationblock;

public class BaseTwo extends BaseOne {
    public BaseTwo() {
        System.out.println("BaseTwo构造器");
    }

    {
        System.out.println("BaseTwo初始化块");
    }

    static {
        System.out.println("BaseTwo静态初始化块");
    }
}

Класс BaseThree

package com.gx.initializationblock;

public class BaseThree extends BaseTwo {
    public BaseThree() {
        System.out.println("BaseThree构造器");
    }

    {
        System.out.println("BaseThree初始化块");
    }

    static {
        System.out.println("BaseThree静态初始化块");
    }
}

Тестовый класс demo2

package com.gx.initializationblock;

/*
     注:这里的ABC对应BaseOne、BaseTwo、BaseThree 
 * 多个类的继承中初始化块、静态初始化块、构造器的执行顺序
     在继承中,先后执行父类A的静态块,父类B的静态块,最后子类的静态块,
     然后再执行父类A的非静态块和构造器,然后是B类的非静态块和构造器,最后执行子类的非静态块和构造器
 */
public class Demo2 {
    public static void main(String[] args) {
        BaseThree baseThree = new BaseThree();
        System.out.println("-----");
        BaseThree baseThree2 = new BaseThree();

    }
}

результат операции

BaseOne静态初始化块
BaseTwo静态初始化块
BaseThree静态初始化块
BaseOne初始化块

BaseOne构造器
BaseTwo初始化块
BaseTwo构造器
BaseThree初始化块
BaseThree构造器
-----
BaseOne初始化块

BaseOne构造器
BaseTwo初始化块
BaseTwo构造器
BaseThree初始化块
BaseThree构造器

При наследовании нескольких классов порядок выполнения блока инициализации, статического блока инициализации и конструктора следующий: выполнить статический блок родительского класса A, статический блок родительского класса B и, наконец, статический блок дочернего класса, а затем выполнить статический блок родительского класса A. Нестатические блоки и конструкторы, затем нестатические блоки и конструкторы класса B и, наконец, нестатические блоки и конструкторы подклассов [Примечание: здесьABCсоответствоватьBaseOne,BaseTwo,BaseThree

Заключение. Порядок выполнения блоков инициализации, статических блоков инициализации и конструкторов при наследовании нескольких классов следующий:Статический блок родительского класса -> статический блок дочернего класса -> блок кода родительского класса -> конструктор родительского класса -> блок кода дочернего класса -> конструктор дочернего класса

Если эта статья была вам полезна, поддержите ее и поставьте лайк QnQ Наконец, блоггеры не большие коровы и не совершают ошибок! Если что-то не так, поправьте меня! Благодарный!