[java] java中的初始化顺序
先看程序:
1 package init_cls; 2 3 class A{ 4 5 {System.out.println("i am in the class A!");} 6 static { System.out.println("static is the class A");} 7 } 8 public class init_cls { 9 {System.out.println("i am in the init_cls");} 10 static{System.out.println("i am static in the init_cls class");} 11 public static void main(String[] args) { 12 // TODO Auto-generated method stub 13 14 A a=new A(); 15 init_cls c=new init_cls(); 16 } 17 18 }
运行结果为:
i am static in the init_cls class
static is the class A
i am in the class A!
i am in the init_cls
从结果中可以看到,当我们只是使用一个类中的方法的时候(在这里使用的init_cls中的main),只初始化静态变量,所以最先输出:i am static in the init_cls class
之后当实例化一个类A的时候,先初始化其中的静态域static ,所以输出:static is the class A
之后初始化非静态域,所以输出:i am in the class A!
最后,只有当我们实例化init_cls类的时候,才初始化了类A中的非静态域,有了输出:i am in the init_cls
类是在任何static成员被访问时候被加载的,构造器也属于static方法,每个类被加载前都会先加载其基类。
这些和python中的初始化顺序非常不同,在python中加载一个包的时候,会从上到下全部初始化,遇到语句时候全部执行
顺便看一个java版的单例模式:
1 public class singleton { 2 private singleton(){System.out.println("created!");} 3 private static singleton obj=new singleton(); 4 public static singleton create(){ 5 return obj; 6 } 7 8 public static void main(String[] args) { 9 // TODO Auto-generated method stub 10 singleton s1 = singleton.create(); 11 singleton s2 = singleton.create(); 12 System.out.println(s1==s2); 13 } 14 }
其中,第3行obj要用static就是因为类singleton没有实例化,obj也就没有初始化,那么create()中就没有obj可以return,但是如果obj为static的话,在main()中,用
singleton.create()之前,就会先把obj初始化。
类是在任何static成员被访问时候被加载的,构造器也属于static方法,每个类被加载前都会先加载其基类。
那么在继承结构中的初始化顺序是怎么样的?
1 class JC1{ 2 {System.out.println("3");} 3 static {System.out.println("1");} 4 } 5 class JC2 extends JC1{ 6 {System.out.println("4");} 7 static {System.out.println("2");} 8 } 9 public class jicheng { 10 11 public static void main(String[] args) { 12 // TODO Auto-generated method stub 13 JC2 jc = new JC2(); 14 } 15 16 }
输出结果:
1 1 2 2 3 3 4 4
可以看书,在继承结构中,先初始化基类-子类的静态变量,再初始化基类-子类的非静态变量
参考资料:thinking in java