相关概念
(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) 类加载顺序:在复杂的类依赖关系中,静态代码块可以用来控制类加载的顺序,确保某些类在其他类之前被加载和初始化。