深入理解类加载机制

之前的博客说了,类加载分为五个阶段

加载->链接(验证+准备+解析)->初始化(使用前的准备)->使用->卸载

今天,遇到一个很有趣的现象:

public class Dervied extends Base {

    private  String name = "dervied";

    public Dervied() {
        tellName();
        printName();
    }
    
    public void tellName() {
        System.out.println("Dervied tell name: " + name);
    }
    
    public void printName() {
        System.out.println("Dervied print name: " + name);
    }

    public static void main(String[] args){
        
        new Dervied();    
    }
}


class Base {

private String name = "base";

 
  

public Base() {
tellName();
printName();
}

public void tellName() {
System.out.println("Base tell name: " + name);
}

public void printName() {
System.out.println("Base print name: " + name);
}
}

 
  

 

 

猜猜输出的结果是什么,或许你会说

Dervied tell name: base
Dervied print name: base
Dervied tell name: dervied
Dervied print name: dervied

一开始我也是这么觉得的,但是,实际上输出的结果却是

Dervied tell name: null
Dervied print name: null
Dervied tell name: dervied
Dervied print name: dervied

 

 

为什么会是Null?,是不是很奇怪,下面我会详细分析

结合着 加载->链接(验证+准备+解析)->初始化(使用前的准备)->使用->卸载 这几个阶段,我们先来看看。

首先,new一个Dervied是调用他的构造方法,

  public Dervied() {
        tellName();
        printName();
    }
我们知道,创建一个子类的实例时,首先会调用其父类无参的构造方法,而调用无参的构造方法之前,会调用父类属性,即调用
private String name = "base";
然后
public Base() {
tellName();
printName();
}


而tellName();这句会输出
System.out.println("Base tell name: " + name);
你可能会想,此时不是已经读取了name吗,为什么最后显示的是Null呢,实际上,虽然此时父类的name是base,但是子类的name还是null,此刻调用的name不是父类的name,而是子类的name,即使写在父类里面。
所以输出的结果是上面我们看到的那样。
我们可以对上面的例子做一点改变:
private  String name = "dervied";改成
private  static String name = "dervied";
这样,就可以访问到子类的name了。
原因是static修饰的变量在类加载的时候就已经被载入了,而我们上面讨论的都是发生在类初始化的时候进行的,所以输出的结果是
 

Dervied tell name: dervied
Dervied print name: dervied
Dervied tell name: dervied
Dervied print name: dervied




转载于:https://www.cnblogs.com/yzjT-mac/p/5868669.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值