class Person
{ { System.out.println("父类代码块"); }
int m=f();
int f() {System.out.println("父类非静态变量"); return 1; }
static int n=g();
static { System.out.println("父类静态代码块"); }
static int g(){System.out.println("父类静态变量");return 2;}
Person() { System.out.println("A Person."); }
}
public class Chinese extends Person
{ { System.out.println("子类代码块");}
int k=k( );
int k( ) { System.out.println("子类非静态变量"); return 3; }
static int i=i( );
static int i( ) { System.out.println("子类静态变量");return 4; }
static{ System.out.println("子类静态代码块"); }
Chinese( ) { super(); System.out.println("A chinese."); }
public static void main(String[] args)
{ Chinese obj=new Chinese( );
boolean b=obj instanceof Chinese;
System.out.println(b);
}
}
执行结果如下:
父类静态变量
父类静态代码块
子类静态变量
子类静态代码块
父类代码块
父类非静态变量
A Person.
子类代码块
子类非静态变量
A chinese.
true
结论如下:刚开始,加载子类之前会先加载父类,加载类的时候会先对类的静态成员进行初始化然后在执行类的静态代码段,所以那两个静态函数会先执行。加载完父类之后就会去加载之类。静态代码段只会在被加载的时候被执行一次。两个类加载完后就会先执行父类的非静态代码段和对非静态的变量进行初始化然后再执行父类的构造函数。接着执行子类的非静态代码段和对子类的非静态变量进行初始化然后执行子类的构造函数。(也就是说在执行构造函数之前会先执行非静态代码段和对非静态成员进行初始化)。
上面还有一个问题就是静态代码区和静态成员变量谁先执行的问题。修改程序进行比较。将父类的静态代码段放到前面,子类的非静态代码段放到后面。修改后程序如下:
class Person
{ { System.out.println("父类代码块"); }
static { System.out.println("父类静态代码块"); }
int m=f();
int f() {System.out.println("父类非静态变量"); return 1; }
static int n=g();
//static { System.out.println("父类静态代码块"); }
static int g(){System.out.println("父类静态变量");return 2;}
Person() { System.out.println("A Person."); }
}
public class Chinese extends Person
{ //{ System.out.println("子类代码块");}
int k=k( );
int k( ) { System.out.println("子类非静态变量"); return 3; }
{ System.out.println("子类代码块");}
static int i=i( );
static int i( ) { System.out.println("子类静态变量");return 4; }
static{ System.out.println("子类静态代码块"); }
Chinese( ) { super(); System.out.println("A chinese."); }
public static void main(String[] args)
{ Chinese obj=new Chinese( );
boolean b=obj instanceof Chinese;
System.out.println(b);
}
}
结果如下:
父类静态代码块
父类静态变量
子类静态变量
子类静态代码块
父类代码块
父类非静态变量
A Person.
子类非静态变量
子类代码块
A chinese.
true
父类的静态代码段在静态成员初始化之前执行,子类的代码段(非静态)在子类的非静态变量初始化后执行。与修改前相反。
这说明静态代码段和静态成员的初始化谁先执行取决于谁写在前面。非静态代码段和非静态成员也是如此。但是静态代码段和静态成员只会在被加载的时候执行一次,之后不会再重复执行。