最近面试遇到几道有关考继承和静态代码这两个知识点的题目,开始非常晕,现在好好总结一下,理清楚顺序。先贴代码。
①类A
class A {
int i = 5;
int j = 5;
{
System.out.println("A1");
}
static{
System.out.println("A.static");
}
A(){
System.out.println("A的constructor");
}
void out(){
System.out.println(i+"----"+j);
}
}
②类B继承类A
class B extends A{
int i = 4;
int j = 4;
{
System.out.println("B1");
}
static{
System.out.println("B.static");
}
B(){
System.out.println("B的constructor");
}
void out(){
System.out.println(i+"@@@@"+j);
}
}
③类C继承类B
class C extends B {
int i = 3;
int j = 3;
{
System.out.println("C1");
}
static {
System.out.println("C.static");
}
C() {
System.out.println("C的constructor");
}
void out() {
System.out.println(i + "####" + j);
}
}
④测试代码
public class Test {
public static void main(String[] args) {
A p = new C();
p.out();
System.out.println(p.i+"****"+p.j);
}
}
先贴执行结果:
A.static
B.static
C.static
A1
A的constructor
B1
B的constructor
C1
C的constructor
3####3
5****5
分析:
(1)类加载器把类装入虚拟机的步骤:装载,链接(校验,准备,解析),初始化,具体如下:
装载:查找导入类或接口的二进制数据;
校验:检查类或接口二进制数据的正确性;
准备:给类的静态变量分配初始化存储空间;
解析:将符号引用转成直接引用;
初始化:激活类的静态变量的初始化java代码块和静态java代码块。
(初始化类中属性是静态代码快的常用用途,但只能用一次!)
类初始化时,先执行父类的静态代码,再执行子类的静态代码,接着是父类如有非静态代码就执行非静态代码,然后执行父类的构造方法,再看子类如果有非静态代码就执行非静态代码,最后执行子类的构造方法。其他方法最后执行。
(2)因为C是继承B,并且重写了父类B的out()方法,所以p调用的是C的out()方法,如果没有重写,则调的是B的out()方法,因为p是A的实例,同理,因为p是A的实例,所以类Test里面的System.out.println(p.i+”**“+p.j);中i,j的值是类A里i,j的值,如果p换成是类B的实例,则是类B里i,j的值。