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执行初始化操作时,非构造方法外面的非静态初始化代码(块),都会被加载到构造方法中,放在其他代码的最前面;
接着是父类的构造方法,子类显式/隐式调用父类的构造方法,而且父类构造方法是放在子类构造方法的首行,如果不存在对应的父类构造方法,则会编译出错。
欢迎讨论交流, 我的主页:http://www.cnblogs.com/GDUT/
我的邮箱:[email protected]