java中类的加载你真的了解吗?

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/u013540324/article/details/53524619

我一直都认为是需求推动技术,所以这里我们先提供一个需求,这里笔者在开发的时候遇到了这样一个问题:
父类:

public class BaseHolder {

public BaseHolder() {
    super();
    initView();
}

public void initView() {

}
}

子类:

public class DetailHolder extends BaseHolder {

public String[]  names=new String[5];

@Override
public void initView() {
    // TODO Auto-generated method stub
    super.initView();
    System.out.println("names数组的大小:"+names.length);
}

public static void main(String[] args) {
    DetailHolder detailHolder = new DetailHolder();
}
}

这个时候输出的结果是什么呢?
0?5?还是报错呢?

显然这里是报错的;(可以猜测一下报什么错误)
这是由于类的加载与初始化的原因;
本篇文章就基于上面的小案例,来做分析;
我们都知道main函数中,当遇到new的时候会去调用构造方法进行一个对象的创建;
但是如果仅仅只是知道这一点的话,上面的问题,该如何解释呢?
首先,要说明的是,上面的说法是没有问题的, 但是不够详细;

接下来咱们直入主题吧:
首先,当我们new的时候,发生了下面几件事情:
1、将相应的.class字节码文件加载到内存中;(类的初始化)
2、将类中的静态成员进行一个初始化
3、调用构造函数(此时并没有执行构造函数里面的内容)
4、对成员变量进行一个初始化;
5、调用构造函数(执行构造函数里面的内容);
6、在堆内存中创建一个对象;
注意:
上面的过程的前提是这个类,没有父类;如果存在这个父类的话,每一步都会让其父类先执行,执行完成后,在执行;

通过上面的步骤,我们来对这个过程进行上面的BaseHolder和DetailHolder进行一个分析;
1、main方法里面new创建了一个DetailHolder;
2、DetailHolder存在父类BaseHolder,就会先去加载父类的class文件,加载好后,加载DetailHolder的class文件
3、对BaseHolder里面的静态成员进行一个初始化,由于没有就不进行,同理,DetailHolder里面也没有
4、调用BaseHolder里面的构造方法,这个时候,会在构造方法里面调用initView();由于子类重写了这个方法,所以就会去调用子类的initView方法;这个时候就会去调用names.length; 这个时候,这个对象初始化了吗?显然没有所以就报空指针异常;终止;
5、为什么没有初始化,我们重新看一下上面的流程,这个是先调用了父类BaseHolder的构造方法,DetailHolder子类的构造方法还没有开始,所以还没有对names进行一个初始化;

基本上分析就到这里。。。下面还有一个小案例,可以测试一下是否真的理解了:

public class BaseHolder {

public BaseHolder() {
    super();
    initView();
}

public void initView() {

}
}


public class TestHolder extends BaseHolder {

public int index=printf("成员变量");
public TestHolder() {
    super();
    System.out.println("构造方法");
}

private int printf(String str) {
    System.out.println(str);
    return 5;
}

@Override
public void initView() {
    // TODO Auto-generated method stub
    super.initView();
    System.out.println("index: "+index);
}

public static void main(String[] args) {
    TestHolder testHolder = new TestHolder();
}   
}

这里我们对应输出结果为:
0
成员变量
构造方法;

安卓交流群 :232748032

展开阅读全文

没有更多推荐了,返回首页