- 概述
- 在Java中所有的变量在使用前都需要初始化。如果我们不初始化,则编译器会为变量初始化一个默认值(例如,int类型的变量的初始化默认值是0)。但是初始化的顺序是什么样的,很多人搞不清楚(我以前也搞不清楚),这篇文章就是为了说明初始化的顺序是什么样的。
- 说明
- 本例子用到四个类:Person、Student、Dog、Order,其中Student继承了Person。
- 下文所说的静态初始化包括:静态代码块初始化、静态变量初始化。
- 下文所说的非静态初始化包括;非静态代码块初始化、普通变量初始化。
- 举例
- Person类代码如下:
1 public class Person implements Serializable {
2
3 // 构造器初始化
4 public Person() {
5 name = "父类构造器初始化10。。。";
6 System.out.println(this.name);
7 }
8
9 // 代码块初始化
10 {
11 String str3 = "父类代码块初始化7。。。";
12 System.out.println(str3);
13 }
14
15 // 静态代码块初始化
16 static {
17 String str4 = "父类静态代码块初始化1。。。";
18 System.out.println(str4);
19 }
20
21 /**
22 *
23 */
24 private static final long serialVersionUID = -2803279990673361523L;
25 private String name;// 姓名
26 private int age;// 年龄
27 // 定义时普通变量初始化
28 private Order order = new Order("父类定义时初始化8。。。");
29 // 定义时静态变量初始化
30 private static Dog dog = new Dog("父类定义时静态初始化2。。。");
31
32 // 代码块初始化
33 {
34 String str1 = "父类代码块初始化9。。。";
35 System.out.println(str1);
36 }
37
38 // 静态代码块初始化
39 static {
40 String str2 = "父类静态代码块初始化3。。。";
41 System.out.println(str2);
42 }
43
44 public Person(String name, int age) {
45 this.name = name;
46 this.age = age;
47 }
48
49 public String getName() {
50 return name;
51 }
52
53 public void setName(String name) {
54 this.name = name;
55 }
56
57 public int getAge() {
58 return age;
59 }
60
61 public void setAge(int age) {
62 this.age = age;
63 }
64
65 public static Dog getDog() {
66 return dog;
67 }
68
69 public static void setDog(Dog dog) {
70 Person.dog = dog;
71 }
72
73 public Order getOrder() {
74 return order;
75 }
76
77 public void setOrder(Order order) {
78 this.order = order;
79 }
80 }
- View Code
- Student类代码如下:
1 public class Student extends Person implements Serializable {
2
3 // 代码块初始化
4 {
5 String str1 = "子类代码块初始化11。。。";
6 System.out.println(str1);
7 }
8
9 // 静态代码块初始化
10 static {
11 String str2 = "子类静态代码块初始化4。。。";
12 System.out.println(str2);
13 }
14
15 /**
16 *
17 */
18 private static final long serialVersionUID = -6642330930111509531L;
19 private float score;// 分数
20 private String grade;// 班级
21 // 定义时普通变量初始化
22 private Order order = new Order("子类定义时初始化12。。。");
23 // 定义时静态变量初始化
24 private static Dog dog = new Dog("子类定义时静态初始化5。。。");
25
26 // 代码块初始化
27 {
28 String str1 = "子类代码块初始化13。。。";
29 System.out.println(str1);
30 }
31
32 // 静态代码块初始化
33 static {
34 String str2 = "子类静态代码块初始化6。。。";
35 System.out.println(str2);
36 }
37
38 // 构造器初始化
39 public Student() {
40 grade = "子类构造器初始化14。。。";
41 System.out.println(this.grade);
42 }
43
44 public float getScore() {
45 return score;
46 }
47
48 public void setScore(float score) {
49 this.score = score;
50 }
51
52 public String getGrade() {
53 return grade;
54 }
55
56 public void setGrade(String grade) {
57 this.grade = grade;
58 }
59
60 public Order getOrder() {
61 return order;
62 }
63
64 public void setOrder(Order order) {
65 this.order = order;
66 }
67
68 public static Dog getDog() {
69 return dog;
70 }
71
72 public static void setDog(Dog dog) {
73 Student.dog = dog;
74 }
75 }
- View Code
- Dog类代码如下:
1 public class Dog implements Serializable {
2
3 /**
4 *
5 */
6 private static final long serialVersionUID = 2239821175446189806L;
7 private String kind;
8 private String name;
9
10 public Dog( String str) {
11 System.out.println(str);
12 }
13
14 public String getKind() {
15 return kind;
16 }
17
18 public void setKind(String kind) {
19 this.kind = kind;
20 }
21
22 public String getName() {
23 return name;
24 }
25
26 public void setName(String name) {
27 this.name = name;
28 }
29
30 }
- View Code
- Order类代码如下:
1 public class Order implements Serializable {
2
3 /**
4 *
5 */
6 private static final long serialVersionUID = 7441323999887439757L;
7
8 private String orderNo;
9 private String orderType;
10
11 public Order( String str) {
12 System.out.println(str);
13 }
14
15 public String getOrderNo() {
16 return orderNo;
17 }
18
19 public void setOrderNo(String orderNo) {
20 this.orderNo = orderNo;
21 }
22
23 public String getOrderType() {
24 return orderType;
25 }
26
27 public void setOrderType(String orderType) {
28 this.orderType = orderType;
29 }
30 }
- View Code
- 执行类如下:
1 public class Test {
2 public static void main(String[] args) {
3 Person p = new Person();
4 Student stu = new Student();
5 }
6 }
- View Code
- 只实例化Person类,执行结果如下图:
- 结论:
- 初始化的总的顺序是:静态初始化-->非静态初始化-->构造器初始化。
- 静态初始化的顺序是:按代码中的顺序进行初始化,谁在前谁先初始化。如上面Person类中所示,虽然构造方法和非静态代码块在最前面,但是从上图的结果可以看出,还是先进行静态初始化。
- 非静态初始化的顺序和静态初始的顺序相同,谁在前谁先初始化。
- 只实例化Student类,执行结果如下:
- 结论:
- 初始化的顺序是:父类静态初始化-->子类静态初始化-->父类非静态初始化-->父类构造器初始化-->子类非静态初始化-->子类构造器初始化。
- 先实例化Person,再实例化Student类,执行结果如下:
- 结论:
- 初始化顺序大体上依然是【静态初始化-->非静态初始化-->构造器初始化】。
- 由于静态变量或代码块属于类,而不属于类的某个实例,其初始化动作只进行一次。在实例化Person类时静态变量或代码块已经初始化过了,因此在实例化Student类时,将不再初始化其父类中的静态变量或代码块。
- 总结
- 初始化的总体顺序:父类静态初始化---->子类静态初始化---->父类非静态初始化---->父类构造方法初始化---->子类非静态初始化---->子类构造方法初始化。
- 静态的初始化的顺序:按代码中的顺序进行初始化,谁在前谁先初始化。
- 非静态初始化的顺序和静态初始化的顺序一致,谁在前谁先初始化。
- 静态初始化只进行一次。