美文网首页Java 杂谈
java小心机(5)| 浅谈类成员初始化顺序

java小心机(5)| 浅谈类成员初始化顺序

作者: KenDoEverything | 来源:发表于2019-01-09 15:29 被阅读0次

    类成员什么时候会被初始化呢?一般来说:"类的代码在初次使用时才被加载",加载过程包括了初始化。

    比如说new A()调用构造函数时,类中全部成员都会被初始化。

    但对于static域(包括静态成员变量、静态代码块、静态方法),当某个static域被调用时,类中的的所有staict就会被初始化,按照定义顺序(即书写顺序)初始化,且只会初始化一次(N个实例共用)``。

    static域的初始化优先级要优于普通成员(即非静态域)

    下文代码例子名称解释:
    静态域:静态代码块、静态成员变量
    非静态域:非静态代码块、非静态成员变量
    (ps:成员方法不包含在里面,因为方法只能讲加载而非初始化)

    在没有继承父类的情况下:

    class HelloA {
        public HelloC helloC1 = new HelloC("普通成员C1 构造函数前");
    
        public HelloA() {
            System.out.println("构造函数A");
        }
    
        public HelloC helloC2 = new HelloC("普通成员C2 构造函数后");
    
        static {
            System.out.println("静态块A");
        }
    
        public HelloC helloC3 = new HelloC("普通成员C3 静态块后");
    
        {
            System.out.println("非静态块A");
        }
    
        public HelloC helloC4 = new HelloC("普通成员C4 非静态块后");
    
        public static HelloC helloC5 = new HelloC("静态成员C5");
    
        public static void main(String[] args) {
            new HelloA();
        }
    }
    
    class HelloC {
        public HelloC(String str) {
            System.out.println(str);
        }
    }
    
    //out:
    静态块A
    静态成员C5
    普通成员C1 构造函数前
    普通成员C2 构造函数后
    普通成员C3 静态块后
    非静态块A
    普通成员C4 非静态块后 构造函数C
    构造函数A
    

    可以看出,初始化顺序为:静态域 -> 非静态域 -> 构造函数
    以上面优先级并按所定义的顺序初始化(即书写顺序)

    在有继承父类的情况下:

    class HelloA extends HelloB{
    
        public HelloA() {
            System.out.println("子类:构造函数A");
        }
    
        static {
            System.out.println("子类:静态块A");
        }
    
        {
            System.out.println("子类:非静态块A");
        }
    
        public static void main(String[] args) {
            new HelloA();
        }
    }
    
    class HelloB {
        public HelloB() {
            System.out.println("父类:构造函数B");
        }
    
        static {
            System.out.println("父类:静态块B");
        }
    
        {
            System.out.println("父类:非静态块B");
        }
    }
    
    //out:
    父类:静态块B
    子类:静态块A
    父类:非静态块B
    父类:构造函数B
    子类:非静态块A
    子类:构造函数A
    

    从结果可以看出,初始化顺序为:父类静态域->子类静态域->父类非静态域->父类构造函数->子类非静态域->子类构造函数

    这里说明一点:这是初始化顺序,不等同于语句程序的执行过程。因此在上面的初始化顺序里没有成员方法(静态或者非静态都没有),这是因为成员方法都是调用了才执行,虽然静态方法已经被加载进了方法区,但初始化过程中并没有执行过。

    推荐阅读:

    「 趣图 」HTTP状态码
    共享单车,要凉凉了?

    点击阅读原文,阅读「java小心机」系列文章

    您的点赞、转发是对我最大的支持!

    image image

    THANDKS

    • End -

    一个立志成大腿而每天努力奋斗的年轻人

    伴学习伴成长,成长之路你并不孤单!

    扫描二维码,关注公众号

    相关文章

      网友评论

        本文标题:java小心机(5)| 浅谈类成员初始化顺序

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