静态代码块和非静态代码块

之前一直只知道有静态代码块。后来才知道还有一个非静态代码块。


静态代码块是指由 static 修饰的大括号里的一段代码,那么非静态代码块就是没有修饰的大括号里的一段代码。就像下面:

# 静态代码块
static {
  若干代码,随便写点啥吧。。。。
}

# 非静态代码块
{
  若干代码,随便写点啥吧。。。。
}

他们的共同特点是:方法名、作用域、返回值、参数一概没有。

详情解析

我们先提出几个问题:

  1. 静态和非静态这两种代码块的区别是什么?
  2. 它们之间的执行顺序是怎么样?和构造函数间的执行顺序又是怎么样的?
  3. 当有继承情况存在的时候,它们的执行顺序又是怎么样?

带着问题,进行接下来的代码分析:

package com.sunyu.javaBase.aboutClass;

public class LoadOrder {
    public static void main(String[] args) {
        /**
        一般情况下的代码测试
         */
        parentTest();

        /**
         * 有继承情况存在下的代码测试
         */
        childrenTest();
    }

    /**
     * 父类测试
     */
    public static void parentTest() {
        Parent parent = new Parent();
        System.out.println();
        System.out.println("-------- 这是两次实例化的分割线 ---------");
        System.out.println();
        parent = new Parent("父类测试");
    }

    /**
     * 子类测试
     */
    public static void childrenTest() {
        Children children = new Children();
        System.out.println();
        System.out.println("-------- 这是两次实例化的分割线 ---------");
        System.out.println();
        children = new Children("子类测试");

    }

}

class Parent {
    {
        System.out.println("父类:执行非静态代码块");
    }

    static {
        System.out.println("父类:执行静态代码块");
    }

    static String name;

    Parent() {
        System.out.println("父类:执行无参构造函数");
    }

    Parent(String name) {
        System.out.println("父类:执行有参构造函数 --->" + name);
    }
}

class Children extends Parent {
    {
        System.out.println("子类:执行非静态代码块");
    }

    static {
        System.out.println("子类:执行静态代码块");
    }

    static String name;

    Children() {
        System.out.println("子类:执行无参构造函数");
    }

    Children(String name) {
        System.out.println("子类:执行有参构造函数 --->" + name);
    }
}

在上面的代码中定义了:主类 LoadOrder父类 Parent子类 Children

执行 parentTest(),测试代码块之间,以及代码块与构造函数之间的执行顺序。执行结果如下:

image.png

parentTest() 中 Parent 实例化了两次。从上面的执行结果来看:

  • 静态代码块执行了一次。众所周知,是类在初始化的时候执行的,也只执行这一次。
  • 非静态代码块执行了两次,而 Parent 实例化了两次。则非静态代码块是在类被实例化的时候执行的,类每实例化一次,则非静态代码块执行一次
  • 两种代码块的执行顺序都在构造函数之前。但是静态代码块在非静态之前。

执行 childrenTest(),测试在继承情况下,代码块,构造函数间的执行顺序。执行结果如下:

image.png

childrenTest()中,Children 实例化了两次。从上面的执行结果看:

  • 不管是父类还是子类,静态代码块优先执行。
  • 在所有的静态代码块执行完后,执行父类相关的代码。先执行父类非静态代码块,再执行父类构造方法;之后执行子类非静态代码块,再执行子类构造方法

结论
  • 静态代码块是在类被加载的时候(即初始化)去执行,且只执行一次
  • 非静态代码块是在类被实例化的时候执行。每被实例化一次,就会被执行一次。
  • 无继承的情况下:执行顺序为:静态代码块 ——> 非静态代码块 ——> 构造函数
  • 有继承的情况下:执行顺序为:父类,子类静态方法 ——> 父类非静态代码块、构造函数 ——> 子类非静态代码块、构造函数

你可能感兴趣的:(静态代码块和非静态代码块)