Java静态代码块,静态属性相关的执行顺序详解

相关概念

(1) 代码块:又叫初始化块,一般指使用大括号包括起来的代码部分,调用的优先级高于构造方法

(2) 静态代码块:在程序进行时,JVM会先进行类的加载,静态代码会随着类的加载而执行,且只会加载一次,用于对类进行初始化,用 static 进行修饰

(3) 非静态代码块:与静态代码块不同,非静态代码块会在每创建一个对象就执行一次

没有继承关系的情况

执行顺序:

在类中存在相关静态代码块和静态属性,且没有类继承关系的情况下,程序执行的顺序如下:

(1) 静态属性和静态代码块,二者优先级相同,执行顺序由定义顺序决定

(2) 非静态属性和非静态代码块,二者优先级相同,执行顺序由定义顺序决定

代码:

public class Test {
    public static void main(String[] args) {
        new A();
    }
}

class A {
    private static int n1 = getVal1();
    private int n2 = getVal2();

    static {
        System.out.println("A的一个静态代码块");
    }

    {
        System.out.println("A的一个非静态代码块");
    }

    public A() {
        System.out.println("A类的构造器");
    }

    public static int getVal1() {
        System.out.println("A的静态属性");
        return 0;
    }

    public int getVal2() {
        System.out.println("A类的普通属性");
        return 0;
    }
}

执行结果:

存在类继承关系的情况

执行顺序:

当拥有静态代码块及静态属性的类存在继承关系时,由于在创建子类对象时会先进行父类的初始化,故会优先执行父类相应的静态代码部分,具体的执行顺序如下

(1) 父类的静态属性和静态代码块,二者优先级相同,执行顺序由定义顺序决定

(2) 子类的静态属性和静态代码块,二者优先级相同,执行顺序由定义顺序决定

(3) 父类的普通代码块和普通属性初始化,二者优先级相同,执行顺序由定义顺序决定

(4) 父类的构造方法

(5) 子类的普通代码块和普通属性初始化,二者优先级相同,执行顺序由定义顺序决定

(6) 子类的构造方法

代码:

public class code_b10ck_detail {
    public static void main(String[] args) {
        //(1) 进行类的加载
        //1.1 先加载 父类 A02  1.2 再加载 B02
        //(2) 创建对象
        //2.1 从子类的构造器开始
        new B02();//创建对象
    }
}

class A02 { //父类
    private static int n1 = getVal01();

    static {
        System.out.println("A02的一个静态代码块");
    }

    {
        System.out.println("A02的一个普通代码块");
    }

    public int n3 = getVal02();//普通属性的初始化

    public static int getVal01() {
        System.out.println("父类的静态属性");
        return 10;
    }

    public int getVal02() {
        System.out.println("父类的普通属性");
        return 10;
    }

    public A02() {  //构造器
        //隐藏了super()
        System.out.println("A02的构造器");
    }
}

class B02 extends A02 {

    private static int n3 = getVal03();

    static {
        System.out.println("B02的一个静态代码块");
    }

    public int n5 = getVal04();

    {
        System.out.println("B02的第一个普通代码块");
    }

    public static int getVal03() {
        System.out.println("子类的静态属性");
        return 10;
    }

    public int getVal04() {
        System.out.println("子类的普通属性");
        return 10;
    }

    public B02() {
        //隐藏了super()
        System.out.println("B02的构造器");
    }
}

执行结果:

注意

只有在静态方法中才能访问到静态属性

静态代码块只能访问静态成员,非静态代码块能够访问任意成员

代码块的使用场景

(1) 初始化类变量:静态代码块常用于初始化类变量,尤其是那些不容易通过直接赋值来初始化的复杂对象

(2) 加载资源:在应用程序启动时,可能需要加载一些资源,如配置文件、驱动程序等,这些资源的加载可以通过静态代码块来实现

(3) 执行一次性的初始化操作:如果某些操作只需要在类加载时执行一次,可以使用静态代码块来实现

(4) 执行静态代码块中的静态代码:有时候,你可能需要在静态代码块中调用静态方法或访问静态字段。

(5) 类加载顺序:在复杂的类依赖关系中,静态代码块可以用来控制类加载的顺序,确保某些类在其他类之前被加载和初始化。

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值