实践出真知,上代码:
package test;
//用来检测创建顺序的类
public class C {
public C(String name,String state) {
System.out.println(name+"的"+state);
}
}
package test;
//父类
public class A {
public A() {
System.out.println("父类的构造方法");
}
static{
System.out.println("父类的静态代码块");
}
public static C c2=new C("父类","静态成员变量");
{
System.out.println("父类的代码块");
}
public C c=new C("父类","普通成员变量");
}
package test;
//子类
public class B extends A{
public B() {
System.out.println("子类的构造方法");
}
public static C c2=new C("子类","静态成员变量");
static{
System.out.println("子类的静态代码块");
}
public C c=new C("子类","普通成员变量");
{
System.out.println("子类的代码块");
}
}
package test;
//运行类
public class Main5 {
public static void main(String[] args) {
//C c=A.c2; //第一处
//new B(); //第二处
}
}
打开第一处注释结果:
由此可知:类的静态代码块和静态成员变量的初始化不需要创建对象,不像一些博文里面描述的第一次创建对象的时候才会初始化静态代码块和静态成员变量,应该说是第一次引用类的时候类的静态代码块和静态成员变量的被初始化,而且只会被初始化一次。
打开第二处注释结果:
先来分析代码块和成员变量间的先后顺序:
由 1与2、3与4 和子父类的代码可以知道:静态代码块和静态成员变量的初始化顺序和代码中出现的顺序有关,普通代码块和普通成员变量也一样
顺序总结:
父类静态代码块/父类静态成员变量(与编写代码的顺序有关)–>子类静态代码块/子类静态成员变量(与编写代码的顺序有关)–>父类普通代码块/父类普通成员变量(与编写代码的顺序有关)–>父类的构造方法–>子类普通代码块/子类普通成员变量(与编写代码的顺序有关)–>子类的构造方法