1 静态代码块
被static关键字修饰的代码块,如
public class A {
static {
System.out.println("A的静态代码块");
}
}
一般用于初始化静态成员变量,可定义多个,在整个JVM运行期间只会执行一次
2 构造代码块(非静态代码块)
public class A {
{
System.out.println("A的构造代码块");
}
}
一般用于抽取多个构造方法内相同的部分(也可以抽出来单独写一个方法,但是方法调用会差生很多局部变量,消耗占内存;而且使用构造代码快可以免去重载构造方式时调用初始化方法的操作,减少代码冗余;),也可以有多个。每次执行new之前都会执行一次。也可用于初始化静态成员变量
两者的相同点:
1 都是在JVM加载类后且构造函数执行之前执行;
2 都可以定义多个;
3 都可以对static变量赋值(初始化);
不同点:
1 静态代码块会在非静态代码块(构造代码块)执行之前执行;
2 当类被JVM加载后,无论有没有执行(调用)构造函数,静态代码块一定会被执行,但是如果不执行(调用)构造函数,非静态代码块就不会执行
3 在JVM运行期间,静态代码块只会在类被加载时执行一次,以后都不会再执行;但是构造代码块每次new之前都会执行一次
4 在非静态代码块中可以对静态成员变量进行操作;但是在静态代码块中,不能操作非静态成员变量
代码执行顺序(包含继承关系)
四条准则:
1 静态早于非静态
2 父类早于子类
3 成员变量初始化、代码块早于构造方法
4 同级别(静态、非静态视作两种级别)成员变量和代码块,执行顺序按照书写顺序自上而下。
根据四条准则,我们总结出代码执行顺序,
1 父类静态成员变量,静态代码块
2 子类静态成员变量,静态代码块
3 父类非静态成员变量,非静态代码块
4 父类构造函数
5 子类非静态成员变量,非静态代码块
6 子类构造方法