疯狂java


您现在的位置: 疯狂软件 >> 新闻资讯 >> 正文

Java的初始化顺序


 

  Java在创建对象之前,是先加载类,然后再创建对象。

  加载类时,会加载静态的成员变量,包括父类的静态成员变量[先加载父类,再加载子类]。

  一、 静态成员变量的初始化

  1 package com.cnblog.GDUTtiantian.init;

  2

  3 /**

  4 * @author GDUTtiantian

  5 * 静态成员变量的初始化

  6 */

  7 public class StaticInit {

  8 private static StaticInit s = new StaticInit();//

  9 private static int index = 0;

  10 private static String ptr;

  11

  12 static {//第一个静态代码块

  13 index = 1;

  14 ptr = name = "newname.";

  15 //System.out.println("name:" + name);//这里编译时会报错:Cannot reference a field before it is defined

  16 System.out.println("name:" + ptr);

  17 System.out.println("The " + index + " Code Block.");

  18 }

  19

  20 private static String name = "GDUTtiantian";

  21

  22 static {//第二个静态代码块

  23 index = 2;

  24 System.out.println("name:" + name);

  25 System.out.println("The " + index + " Code Block.");

  26 }

  27

  28 public StaticInit(){

  29 System.out.println("Constructor:" + this.getClass().getSimpleName());

  30 }

  31

  32 public static void main(String[] args) {

  33 System.out.println("------------------");

  34 StaticInit s = new StaticInit();

  35 System.out.println("------------------");

  36 }

  37

  38 static {//第三个静态代码块

  39 index = 3;

  40 System.out.println("The " + index + " Code Block.");

  41 }

  42

  43 }

  运行结果:

  1 Constructor:StaticInit

  2 name:newname.

  3 The 1 Code Block.

  4 name:GDUTtiantian

  5 The 2 Code Block.

  6 The 3 Code Block.

  7 ------------------

  8 Constructor:StaticInit

  9 ------------------

  二、 静态成员变量和非静态成员变量的初始化

  1 package com.cnblog.GDUTtiantian.init;

  2

  3 /**

  4 * @author GDUTtiantian

  5 * 静态成员变量和非静态成员变量的初始化

  6 */

  7 public class StaticInit2 {

  8 //private static Static2 s = new Static2();//

  9 private static int index = 0;

  10 private static String ptr;

  11

  12 {//第一个【非】静态代码块

  13 //这里编译不会出错,主要是当前代码块处于name属性的作用域范围。

  14 this.flag = "GDUT";

  15 System.out.println("[非静态变量初始化]:代码块1");

  16 }

  17

  18 {//第两个【非】静态代码块

  19 System.out.println("[非静态变量初始化]:代码块2");

  20 }

  21

  22 private String flag = "tiantian";

  23

  24 static {//第一个静态代码块

  25 index = 1;

  26 ptr = name = "newname.";

  27 //System.out.println("name:" + name);//这里编译时会报错:Cannot reference a field before it is defined

  28 System.out.println("name:" + ptr);

  29 System.out.println("The " + index + " Code Block.");

  30 }

  31

  32 private static String name = "GDUTtiantian";

  33

  34 static {//第二个静态代码块

  35 index = 2;

  36 System.out.println("name:" + name);

  37 System.out.println("The " + index + " Code Block.");

  38 }

  39

  40 public StaticInit2(){

  41 System.out.println("Constructor:" + this.getClass().getSimpleName());

  42 }

  43

  44 public static void main(String[] args) {

  45 System.out.println("------------------");

  46 StaticInit2 s = new StaticInit2();

  47 System.out.println("------------------");

  48 }

  49

  50 static {//第三个静态代码块

  51 index = 3;

  52 System.out.println("The " + index + " Code Block.");

  53 }

  54

  55 {//第三个【非】静态代码块

  56 System.out.println("[非静态变量初始化]:代码块3");

  57 }

  58

  59 }

  运行结果:

  1 name:newname.

  2 The 1 Code Block.

  3 name:GDUTtiantian

  4 The 2 Code Block.

  5 The 3 Code Block.

  6 ------------------

  7 [非静态变量初始化]:代码块1

  8 [非静态变量初始化]:代码块2

  9 [非静态变量初始化]:代码块3

  10 Constructor:StaticInit2

  11 ------------------

  三、 总结:

  还有一种情况是,父类和子类的成员变量的初始化情况,父类含有静态和非静态成员变量,子类也含有静态和非静态成员变量。

  在这种情况下,会先初始化父类的静态成员变量,然后再是子类的静态成员变量; <-----【静态成员变量初始化】

  接着初始化父类的非静态成员变量,最后是子类的非静态成员变量。 <------【非静态成员变量初始化】

  补充:

  JVM执行初始化操作时,非构造方法外面的非静态初始化代码(块),都会被加载到构造方法中,放在其他代码的最前面;

  接着是父类的构造方法,子类显式/隐式调用父类的构造方法,而且父类构造方法是放在子类构造方法的首行,如果不存在对应的父类构造方法,则会编译出错。