class
A {
static
{
System.out.print(
"A"
);
}
public
A() {
System.out.print(
"a"
);
}
void
say() {
System.out.print(
"1"
);
}
}
class
B
extends
A {
static
{
System.out.print(
"B"
);
}
public
B() {
System.out.print(
"b"
);
}
void
say() {
System.out.print(
"2"
);
}
}
public
class
Hello {
public
static
void
main(String[] args) {
A ab =
new
B();
ab.say();
ab =
new
B();
ab.say();
}
}
此段程序运行结果为:
ABab2ab2;
解析一、
1.实例化B B所在类未加载 首先加载B所在类B B有父类A 所以类加载顺序 A,B 打印AB
2.实例化B 调用父类构造方法 再调用自身构造方法 打印ab
3.B中重写了父类say 直接调用本身类的say 打印2
4.第二次实例化B 类加载只会执行一次 1中已完成 直接重复2 3步骤 打印ab2
ABab2ab2;
解析二、
加载顺序 父类静态成员->父类静态代码块->子类静态成员->子类静态代码块->父类普通成员->父类代码块->父类构造函数->子类普通成员->子类代码块->子类构造函数
只有类第一次加载的时候加载静态成员与代码块
加载顺序 父类静态成员->父类静态代码块->子类静态成员->子类静态代码块->父类普通成员->父类代码块->父类构造函数->子类普通成员->子类代码块->子类构造函数
只有类第一次加载的时候加载静态成员与代码块