关于Java编译时和运行时的差异

关于Java编译时和运行时的差异
//有兴趣的人,试试自己的基础,看看这个程序输出的是什么?
//第一次解析,难免有点错漏,欢迎阅读者能指出我的错误,并与我分享,大家共同进步! 本人语文水平not good, 错别字就不说了 。。

//关注本人CSDN博客:http://my.csdn.net/erix1991

class Base {
    private int a = 2;
    public Base() {
    this.display();         
}
public void display() {
    System.out.println(a);
    }
}

class Derived extends Base {
    private int a = 22;
    public Derived() {
    //super();
    a = 222;
}
public void display() {
    System.out.println(a);
    }
}


public class TestO {
public static void main(String[] args) {
new Derived();
}
}





//输出的是什么?  2, 22, 222?  都是错,答案输出的是0;   这是为什么? 

        首先明白一点,子类继承父类,如果有多个同名的实例变量,但是子类的同名实例并不能覆盖父类的实例变量
 而且子类在堆空间里面分配两个 a实例的变量,而不是一个!
       对于Java的构造函数,很多人都吧它理解成Java的对象都是通过构造函数来创建,其实这是错的,其实Java的构造函数只负责做一件事,就是执行对象的实例变量进行初始化!
       在类被虚拟机加载到虚拟机里的时候,对象所占的内存已经被分配下来了,对于基本类型的变量是0或者是false; 对于引用类型的变量,默认的就是null;

      我们再来看看这个程序执行的顺序吧。
        1,首先Derived 这个类被加载到虚拟机,主函数执行new Derived()在堆内存分配空间,因为Derived 继承与Base,那么内存里应该有两份a的实例变量,它们的默认值都是0
        2,Derived子类执行构造函数初始化,我们知道,子类初始化,必先执行父类的构造函数,这个程序里隐含了super()的父类构造函数在子类的构造函数里
        3,执行super(),调用父类的构造函数,此时执行this.display(),那么这个this指向的是什么呢? 答案是Derived! 为什么不是Base;因为这个父类的构造函数时通过Derived对象来调用,那么这个this当然是Derived的!
       4,那么执行this.display()那么当然输出的是0里,因为Derived的a 还没有来的及初始化,在内存空间的默认值还是0;
      
        那么需要解析的是,在Java里,当变量的编译时和运行时类型是不同的,系统在调用它的实例变量和实例方法时存在上述的差异, 就这个程序来说,在父类里,编译的时候,this.display(),这个this是父类,但是当运行的时候,那么this就变成子类的引用了
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值