init是instance实例构造器,对非静态变量解析初始化,而clinit是class类构造器对静态变量,静态代码块进行初始化
class X {
static Log log = LogFactory.getLog(); // <clinit>
private int x = 1; // <init>
X(){
// <init>
}
static {
// <clinit>
}
}
<init>
与<clinit>
<init>
Java在编译之后会在字节码文件中生成<init>
方法,称之为实例构造器,该实例构造器会将语句块,变量初始化,调用父类的构造器等操作收敛到<init>
方法中,收敛顺序(这里只讨论非静态变量和语句块)为:
1. 父类变量初始化
2. 父类语句块
3. 父类构造函数
4. 子类变量初始化
5. 子类语句块
6. 子类构造函数
所谓收敛到<init>
方法中的意思就是,将这些操作放入到<init>
中去执行
<clinit>
Java在编译之后会在字节码文件中生成<clinit>
方法,称之为类构造器,类构造器同实例构造器一样,也会将静态语句块,静态变量初始化,收敛到<clinit>
方法中,收敛顺序为:
1. 父类静态变量初始化
2. 父类静态语句块
3. 子类静态变量初始化
4. 子类静态语句块
<clinit>
方法是在类加载过程中执行的,而<init>
是在对象实例化执行的,所以<clinit>
一定比<init>
先执行。所以整个顺序就是:
1. 父类静态变量初始化
2. 父类静态语句块
3. 子类静态变量初始化
4. 子类静态语句块
5. 父类变量初始化
6. 父类语句块
7. 父类构造函数
8. 子类变量初始化
9. 子类语句块
10. 子类构造函数
public class Parent {
static int a = 1;
int b = 1;
static {
System.out.println("parent static block(a):" + (++a));
}
{
System.out.println("parent block(b):" + (++b));
}
public Parent() {
System.out.println("parent construction");
}
}
public class Child extends Parent {
static int a = 1;
int b = 1;
static {
System.out.println("child static block(a):" + (++a));
}
{
System.out.println("child block(b):" + (++b));
}
public Child() {
System.out.println("child construction");
}
public static void main(String[] args) {
new Child();
}
}
输出结果为:
parent static block(a):2
child static block(a):2
parent block(b):2
parent construction
child block(b):2
child construction
---------------------
原文:https://blog.csdn.net/u013309870/article/details/72975536
版权声明:本文为博主原创文章,转载请附上博文链接!