类的加载顺序 (一、编译时常量与运行时常量)
编译时常量在编译阶段会写死到.class中
而且会存入到 调用这个常量的方法所在的类的常量池中
如下代码编译后 删除Parents01.class 后依然可以正常执行
public class MyTest01 { public static void main(String[] args) { // TODO Auto-generated method stub System.out.println(Parents01.VALUE); } } class Parents01{ public static final String VALUE = "Parents01 const VALUE"; static { System.out.println("this is Parents01 static block"); } }//out:Parents01 const VALUE
说明VALUE被写入了MyTest01中
运行时常量:(编译时不加载,类初始化时才加载)
public class MyTest01 { public static void main(String[] args) { // TODO Auto-generated method stub System.out.println(Parents01.VALUE); } } class Parents01{ public static final String VALUE = new String("Parents01 const VALUE"); static { System.out.println("this is Parents01 static block"); } }//out:Parents01 const VALUE
另外 用子类调用父类的 static字段 并不会初始化子类static域
具体代码如下
public class MyTest01 { public static void main(String[] args) { // TODO Auto-generated method stub System.out.println(Children01.VALUE); } } class Parents01{ public static String VALUE = "Parents01 const VALUE"; static { System.out.println("this is Parents01 static block"); } } class Children01 extends Parents01{ static { System.out.println("this is Children01 static block"); } }
//~out:
this is Parents01 static block
Parents01 const VALUE
将VALUE修改为final 则 一个static域都不执行。
static域在static字段后初始化,父类先于子类初始化:
public class MyTest01 { public static void main(String[] args) { // TODO Auto-generated method stub new Children01(); } } class Parents01{ public static Sub01 sub = new Sub01(); static { System.out.println("this is Parents01 static block"); } } class Children01 extends Parents01{ static { System.out.println("this is Children01 static block"); } } class Sub01{ Sub01(){ System.out.println("this is Sub01"); } } //~out: this is Sub01 this is Parents01 static block this is Children01 static block