Java基础知识之初始化——初始化顺序

  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. 结论:
        1. 初始化顺序大体上依然是【静态初始化-->非静态初始化-->构造器初始化】。
        2. 由于静态变量或代码块属于类,而不属于类的某个实例,其初始化动作只进行一次。在实例化Person类时静态变量或代码块已经初始化过了,因此在实例化Student类时,将不再初始化其父类中的静态变量或代码块。
  4. 总结
    1. 初始化的总体顺序:父类静态初始化---->子类静态初始化---->父类非静态初始化---->父类构造方法初始化---->子类非静态初始化---->子类构造方法初始化。
    2. 静态的初始化的顺序:按代码中的顺序进行初始化,谁在前谁先初始化。
    3. 非静态初始化的顺序和静态初始化的顺序一致,谁在前谁先初始化。
    4. 静态初始化只进行一次。
posted @ 2017-11-12 15:54  我的名字叫红  阅读(312)  评论(0编辑  收藏  举报