Java 对象启动顺序

Java 对象启动顺序

  1. java 对象初始化时,会先加载对应的类,随后加载其基类(如果存在基类);
  2. 先从基类执行static 初始化,后执行子类static 初始化。static初始化顺序:静态变量和静态初始化块的执行顺序取决于它们的代码位置顺序。
  3. 此时,类加载完毕,开始对象的初始化。先执行基类初始化,后执行衍生类初始化。
    • 对象初始化的顺序:
      • 属性得到初值:基本值类型为默认值;对象句柄为null;
        • 定义为final非静态基本数据类型的成员变量此时也会被初始化, 注意Integer等包装类不行;
        • 有且只有定义为final非静态的String成员变量,采用的“=”赋值初始化会被执行(非new)。
      • 属性定义时的初始化(例如int i =1)和代码块,的执行顺序取决于它们的代码位置顺序。
      • 构造函数;

示例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
package info.victorchu.cinit;

public class Parent {
static Sample staticSample = new Sample("Parent:静态成员staticSample初始化");
static {
System.out.println("Parent:类static块执行");
Sample.init(staticSample,"Parent:类static块>>静态成员staticSample初始化");
}

{
System.out.println("Parent:对象非静态块1执行");
}
Sample sampleField1 = new Sample("Parent:普通成员sampleField1初始化");
final Sample finalSample = new Sample("Parent:final成员finalSample初始化");

Parent() {
sampleField1 = new Sample("Parent:构造函数>>普通成员sampleField1初始化");
viewValues();
System.out.println("Parent:构造函数被调用");
}

//调用子类的override函数,访问子类未初始化的非静态成员变量
public void viewValues() {

}
}
public class Child extends Parent{
static Sample staticChildSample = new Sample("Child:静态成员staticChildSample初始化");
static {
System.out.println("Child:类static块执行");
Sample.init(staticChildSample,"Child:类static块>>静态成员staticChildSample初始化");
}
final Sample finalChildSample = new Sample("Child:final成员finalChildSample初始化");
Child() {
System.out.println("Child:构造函数被调用");
}

private int derive0 = 888;
final private int derive1 = 888;
final private Integer derive2 = 888;
final private String derive3 = new String("Hello World");
final private String derive4 = "Hello World";

@Override
public void viewValues() {
System.out.println("子类成员变量derive0 = " + derive0);
System.out.println("子类成员变量derive1 = " + derive1);
System.out.println("子类成员变量derive2 = " + derive2);
System.out.println("子类成员变量derive3 = " + derive3);
System.out.println("子类成员变量derive4 = " + derive4);
System.out.println("子类成员变量finalChildSample = " + finalChildSample);
}
}
public class ClassInitOrder {
public static void main(String[] args) {
Parent parent = new Child();
}
}
class Sample {
String s;
Sample(String s) {
this.s = s;
System.out.println(s);
}
Sample(String s,String old) {
this.s = s;
System.out.println(s+"->"+old);
}
static Sample init(Sample s,String str) {
if(s == null){
return new Sample(str);
}else {
return new Sample(str,s.toString());
}
}
@Override
public String toString() {
return this.s;
}
}

输出:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
Parent:静态成员staticSample初始化
Parent:类static块执行
Parent:类static块>>静态成员staticSample初始化->Parent:静态成员staticSample初始化
Child:静态成员staticChildSample初始化
Child:类static块执行
Child:类static块>>静态成员staticChildSample初始化->Child:静态成员staticChildSample初始化
Parent:对象非静态块1执行
Parent:普通成员sampleField1初始化
Parent:final成员finalSample初始化
Parent:构造函数>>普通成员sampleField1初始化
子类成员变量derive0 = 0
子类成员变量derive1 = 888
子类成员变量derive2 = null
子类成员变量derive3 = null
子类成员变量derive4 = Hello World
子类成员变量finalChildSample = null
Parent:构造函数被调用
Child:final成员finalChildSample初始化
Child:构造函数被调用