Java基礎知識之初始化——初始化順序
阿新 • • 發佈:2017-11-12
子類 初始 zab 不清楚 static urn extend rgs end
- 概述
- 在Java中所有的變量在使用前都需要初始化。如果我們不初始化,則編譯器會為變量初始化一個默認值(例如,int類型的變量的初始化默認值是0)。但是初始化的順序是什麽樣的,很多人搞不清楚(我以前也搞不清楚),這篇文章就是為了說明初始化的順序是什麽樣的。
- 說明
- 本例子用到四個類:Person、Student、Dog、Order,其中Student繼承了Person。
- 下文所說的靜態初始化包括:靜態代碼塊初始化、靜態變量初始化。
- 下文所說的非靜態初始化包括;非靜態代碼塊初始化、普通變量初始化。
- 舉例
- Person類代碼如下:
1 public class Person implements
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類時,將不再初始化其父類中的靜態變量或代碼塊。
- 結論:
- Person類代碼如下:
- 總結
- 初始化的總體順序:父類靜態初始化---->子類靜態初始化---->父類非靜態初始化---->父類構造方法初始化---->子類非靜態初始化---->子類構造方法初始化。
- 靜態的初始化的順序:按代碼中的順序進行初始化,誰在前誰先初始化。
- 非靜態初始化的順序和靜態初始化的順序一致,誰在前誰先初始化。
- 靜態初始化只進行一次。
Java基礎知識之初始化——初始化順序