java 父类初始化,Java中父类的构造函数调用在类变量的初始化之前!!

如题!以前初步了解过class文件的加载步骤,大部分文章里都提到了:

类变量的初始化在构造方法之前!!!

这个很好理解,比如下面的代码

public class A{

int a = 1;

public A(){

System.out.println(a); //1

a = 3;

System.out.println(a); //3

}

}

上面代码很好理解吧,在构造函数里a已经初始化完成,直接输出1,再次赋值时会覆盖上个值。

那么我们再看下面的代码:

public class Main {

public static void main(String[] args){

new B();

}

static class A{

int a = 3;

public A(){

System.out.println("this is A "+a);

a = 2;

display();

}

public void display(){

System.out.println("this is A display "+a);

}

}

static class B extends A{

int a = 1;

public B(){

super();

System.out.println("this is B "+a);

a = 5;

display();

}

@Override

public void display(){

System.out.println("this is B display "+a);

}

}

}

输出结果大家还能猜到吗?

5415198e64ae

输出结果

起初看到这个结果我也很诧异!!!

第二行的结果为什么会是0??不应该是1吗?(方法的重写,调用子类的display,访问子类的a)

然而事实就是如此,唯一能解释通的就是:

父类构造方法的调用在类变量的初始化之前!!!

如果接受这个概念的话,上面的结果就能解释通了,父类的构造方法中调用B的display,而此时B中的a还没有初始化,所以输出默认值,0;

同样的,下面这几行代码就也能接受了,父类的初始化(也就是父类的加载)必须在子类之前完成,不然这个类变量的super怎么访问父类的属性呢?

static class B extends A{

int a = super.a;

public B(){

System.out.println("this is B "+a);

a = 5;

display();

}

}

当然这种只靠猜,说服力可能还不太够,下面是调用javap命令后的输出内容,懂JVM指令的可以自行查看一下!(删除了构造方法中的输出和display中输出的字符串)

G:\WorkSpace\jedisTest\out\production\jedisTest>javap -c com.company.Main$B

Compiled from "Main.java"

class com.company.Main$B extends com.company.Main$A {

int a;

public com.company.Main$B();

Code:

0: aload_0

1: invokespecial #1 // Method com/company/Main$A."":()V

4: aload_0

5: iconst_1

6: putfield #2 // Field a:I

9: aload_0

10: iconst_5

11: putfield #2 // Field a:I

14: aload_0

15: invokevirtual #3 // Method display:()V

18: return

public void display();

Code:

0: getstatic #4 // Field java/lang/System.out:Ljava/io/PrintStream;

3: aload_0

4: getfield #2 // Field a:I

7: invokevirtual #5 // Method java/io/PrintStream.println:(I)V

10: return

}

恕编者目前水平有限,对JVM还不太熟悉,有几个命令还不太熟悉,所以此处不做解释,一段时间后会再来续写,对每一行指令做出解释!但可以告诉大家执行的顺序:

父类类变量初始化->父类构造函数->子类类变量->子类构造函数。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值