相信在面试中,你经常会做到子类和父类然后问你代码加载的顺序
极力推荐
1.顺序总结为:
父类static变量->子类static变量->父类成员变量->父类代码块->父类构造器->父类普通方法->子类成员变量->子类代码块->子类构造器->子类普通方法->main函数(说明:static变量包括static变量和static代码块,按位置顺序执行)
代码
2.1无继承的代码
public class TestClass {
public static void main(String[] args) {
// TODO Auto-generated method stub
System.out.println("Creating new Cupboard() in main");
new Cupboard();
System.out.println("Creating new Cupboard() in main");
new Cupboard();
t2.f2(1);
t3.f3(1);
}
static Table t2 = new Table();
static Cupboard t3 = new Cupboard();
}
// : StaticInitialization.java
// Specifying initial values in a
// class definition.
class Bowl {
Bowl(int marker) {
System.out.println("Bowl(" + marker + ")");
}
void f(int marker) {
System.out.println("f(" + marker + ")");
}
}
class Table {
static Bowl b1 = new Bowl(1);
static{
System.out.println("Table() static 1");
}
Table() {
System.out.println("Table()");
b2.f(1);
}
void f2(int marker) {
System.out.println("f2(" + marker + ")");
}
Bowl b10 = new Bowl(10);
{
System.out.println("Table() non-static");
}
Bowl b11 = new Bowl(11);
static Bowl b2 = new Bowl(2);
static{
System.out.println("Table() static 2");
}
}
class Cupboard {
Bowl b3 = new Bowl(3);
static Bowl b4 = new Bowl(4);
Cupboard() {
System.out.println("Cupboard()");
b4.f(2);
}
void f3(int marker) {
System.out.println("f3(" + marker + ")");
}
static Bowl b5 = new Bowl(5);
}
输出顺序为
Bowl(1)
Table() static 1
Bowl(2)
Table() static 2
Bowl(10)
Table() non-static
Bowl(11)
Table()
f(1)
Bowl(4)
Bowl(5)
Bowl(3)
Cupboard()
f(2)
Creating new Cupboard() in main
Bowl(3)
Cupboard()
f(2)
Creating new Cupboard() in main
Bowl(3)
Cupboard()
f(2)
f2(1)
f3(1)
2.2 有继承的类的初始化顺序
//: Beetle.java
// The full process of initialization.
class Insect {
int i = 9;
int j;
Insect() {
prt("i = " + i + ", j = " + j);
j = 39;
}
static{
System.out.println("Insert static block0");
}
static int x1 =
prt("static Insect.x1 initialized");
static int prt(String s) {
System.out.println(s);
return 47;
}
static{
System.out.println("Insert static block1");
}
}
public class Beetle extends Insect {
int k = prt("Beetle.k initialized");
Beetle() {
prt("k = " + k);
prt("j = " + j);
}
static int x2 =
prt("static Beetle.x2 initialized");
static int prt(String s) {
System.out.println(s);
return 63;
}
public static void main(String[] args) {
prt("Beetle constructor"); //flag 1
Beetle b = new Beetle(); //flag 2
}
} ///:~
输出结果
Insert static block0
static Insect.x1 initialized
Insert static block1
static Beetle.x2 initialized
Beetle constructor
i = 9, j = 0
Beetle.k initialized
k = 63
j = 39
//如果只把flag 1 那条语句注释掉,输出内容如下:
Insert static block0
static Insect.x1 initialized
Insert static block1
static Beetle.x2 initialized
i = 9, j = 0
Beetle.k initialized
k = 63
j = 39
//如果只把flag 2 那条语句注释掉,输出内容如下:
Insert static block0
static Insect.x1 initialized
Insert static block1
static Beetle.x2 initialized
Beetle constructor
3.总结为
父类的static修饰的属性,代码块和方法(按照出现顺序执行)=》子类的static修饰的属性,代码块和方法=》当前主程序=》父类的普通属性=》父类的普通代码块=》父类的构造方法=》子类的普通属性=》子类的普通代码块=》子类的构造方法=》子类的普通方法
==注意:父类的普通方法根据子类的调用的父类的普通方法的前后顺序来
(子类调用父类的普通方法 先调用哪个就先执行哪个)
具体的参考代码见
参考资料1
参考资料2