1. 程式人生 > >Java基礎知識之初始化——初始化順序

Java基礎知識之初始化——初始化順序

子類 初始 zab 不清楚 static urn extend rgs end

  1. 概述
    1. 在Java中所有的變量在使用前都需要初始化。如果我們不初始化,則編譯器會為變量初始化一個默認值(例如,int類型的變量的初始化默認值是0)。但是初始化的順序是什麽樣的,很多人搞不清楚(我以前也搞不清楚),這篇文章就是為了說明初始化的順序是什麽樣的。
  2. 說明
    1. 本例子用到四個類:Person、Student、Dog、Order,其中Student繼承了Person。
    2. 下文所說的靜態初始化包括:靜態代碼塊初始化、靜態變量初始化。
    3. 下文所說的非靜態初始化包括;非靜態代碼塊初始化、普通變量初始化。
  3. 舉例
    1. 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
    2. 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
    3. 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
    4. 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
    5. 執行類如下: 技術分享
      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
    6. 只實例化Person類,執行結果如下圖:
      1.   技術分享
      2. 結論:
        1. 初始化的總的順序是:靜態初始化-->非靜態初始化-->構造器初始化。
        2. 靜態初始化的順序是:按代碼中的順序進行初始化,誰在前誰先初始化。如上面Person類中所示,雖然構造方法和非靜態代碼塊在最前面,但是從上圖的結果可以看出,還是先進行靜態初始化。
        3. 非靜態初始化的順序和靜態初始的順序相同,誰在前誰先初始化。
    7. 只實例化Student類,執行結果如下:
      1.   技術分享
      2. 結論:
        1.  初始化的順序是:父類靜態初始化-->子類靜態初始化-->父類非靜態初始化-->父類構造器初始化-->子類非靜態初始化-->子類構造器初始化。
    8. 先實例化Person,再實例化Student類,執行結果如下:
      1. 技術分享
      2. 結論:
        1. 初始化順序大體上依然是【靜態初始化-->非靜態初始化-->構造器初始化】。
        2. 由於靜態變量或代碼塊屬於類,而不屬於類的某個實例,其初始化動作只進行一次。在實例化Person類時靜態變量或代碼塊已經初始化過了,因此在實例化Student類時,將不再初始化其父類中的靜態變量或代碼塊。
  4. 總結
    1. 初始化的總體順序:父類靜態初始化---->子類靜態初始化---->父類非靜態初始化---->父類構造方法初始化---->子類非靜態初始化---->子類構造方法初始化。
    2. 靜態的初始化的順序:按代碼中的順序進行初始化,誰在前誰先初始化。
    3. 非靜態初始化的順序和靜態初始化的順序一致,誰在前誰先初始化。
    4. 靜態初始化只進行一次。

Java基礎知識之初始化——初始化順序