美文网首页java面试
JAVA中对象的创建过程

JAVA中对象的创建过程

作者: HopeMan | 来源:发表于2018-07-21 20:36 被阅读143次

    在上一篇文章中讲述了java对象的销毁和垃圾回收器的工作方式,这篇文章将讲下java对象的创建,这对我们平时的开发也有一定的帮助。

    假如存在一个名为User的类,User的成员变量有静态的和非静态的。

    1:当创建User类的对象或调用其静态成员变量或静态方法时,java编译器会先定位User.class

    2:java装载机ClassLoader加载User.class,此时会初始化其静态成员变量。因此,静态成员变量只会在Class首次被装载时初始化一次

    3:通过new User()创建对象,此时会在堆区域为其分配存储空间

    4:该存储空间会被清零,自动为User对象的成员变量设置默认值(基本类型成员变量,如int会被赋值0),如果有引用,设置为null

    5:执行成员变量的初始化(例如int times = 9)

    6:调用构造方法,完成类的完整初始化

    还有一点需要注意,就是出现继承时的构造方法的调用顺序

    如果User继承基类BaseBean,那么在创建User对象,上述的第4步走完之后,顺序会发生变化

    5:调用基类BaseBean的构造方法

    6:执行User成员变量的初始化

    7:调用User的构造函数

    初始化不当会产生的问题

    下面这个程序就是由于构造方法初始化不当引起问题的典型。看下面两个类的定义:

    最后是以上程序的执行结果。

    分析:在User对象分配堆区域,并对区域清零后,此时成员变量都被赋予了默认值,

    1:调用基类构造函数,打印BaseBean

    2:调用init()方法,由于基类的此方法被User重写,所以此时调用User对象的init()方法,但此时name变量还未被初始化,只是被赋予了默认值而已,因此打印的是User name:null(此处很惊讶,是造成我们要讨论的问题的原因)

    3:完成成员变量初始化和调用User构造函数

    问题分析:User子类在未完全初始化的情况下访问其成员变量,造成null的出现

    总结

    在定义构造函数时,尽量快速完成初始化,尽量不要调用其他方法,因为你不知道子类是否会重写被调用的方法,就像上面的例子,在init()中就会出现null的情况,如果此时直接使用name就会报空指针。如果非要调用方法,可以将方法定义为final 或者private(默认也会被final修饰)类型,避免被子类重写,产生问题。

    相关文章

      网友评论

        本文标题:JAVA中对象的创建过程

        本文链接:https://www.haomeiwen.com/subject/rikkmftx.html