博客
关于我
Java创建对象的初始化顺序
阅读量:793 次
发布时间:2023-01-28

本文共 2492 字,大约阅读时间需要 8 分钟。

Java类初始化顺序问题解析

2023年9月25日 12:48:27 1849文章字数

作为一名Java开发人员,在类的初始化过程中常会遇到一些疑惑,尤其是静态和非静态成员的初始化顺序。这一点特别值得注意,尤其是在继承关系中,父类和子类的初始化顺序可能会影响程序的运行结果。本文将从基础到上手,帮助大家理解和分析Java类的初始化机制。

一、类初始化的基本概念

在Java中,每当我们创建一个对象时,类的初始化都会被触发。初始化过程分为以下几个阶段:

  • 静态成员的初始化:首先,所有静态变量和静态方法会被初始化。静态成员包括类变量、静态方法以及静态代码块。这些成员的初始化顺序是按照定义顺序执行的。

  • 非静态成员的初始化:在静态成员初始化完成后,非静态成员(包括实例变量、实例方法和非静态代码块)会被初始化。非静态成员的初始化仅在对象被创建时执行一次,与类的初始化顺序密切相关。

  • 构造函数的执行:最后,在非静态成员的初始化完成后,构造函数(或者称为初始化函数)会被调用,以完成对象的具体化。

  • 二、父类与子类的初始化顺序分析

    在Java中,类之间继承关系会影响初始化的顺序。当一个子类继承自父类时,父类和子类的初始化都会被触发。其执行顺序如下所示:

  • 父类静态部分初始化:首先,父类的静态变量和静态方法会被初始化。静态代码块内的逻辑会按照定义顺序依次执行。

  • 子类静态部分初始化:父类初始化完成后,子类的静态部分(静态变量、静态方法和静态代码块)会被初始化。

  • 父类非静态部分初始化:在子类静态部分初始化完成后,父类的非静态成员会被初始化(如果父类有非静态部分的话)。

  • 子类非静态部分初始化:父类非静态部分初始化完成后,子类的非静态成员会被初始化。

  • 子类构造函数调用:最后,子类的构造函数会被调用,用于初始化对象的具体属性和状态。

  • 三、示例分析

    为了更好地理解上述机制,我们来看一个典型的Java例子:父类和子类的初始化顺序分析。

    package com.zhang.test;class Parent {    private static int j = method();    private int i = test();    static {        System.out.println("Parent static block");    }    {        System.out.println("Parent non-static block");    }    Parent() {        System.out.println("Parent constructor");    }    public static int method() {        System.out.println("Parent method");        return 1;    }    public static int method() {        System.out.println("Parent method");        return 1;    }    public int test() {        System.out.println("Parent test");        return 1;    }}class Child extends Parent {    private static int j = method();    private int i = test();    static {        System.out.println("Child static block");    }    {        System.out.println("Child non-static block");    }    Child() {        System.out.println("Child constructor");    }    public static int method() {        System.out.println("Child method");        return 1;    }    public int test() {        System.out.println("Child test");        return 1;    }}

    四、程序运行结果分析

    在上述代码中,父类和子类都定义了静态和非静态成员。通过分析我们可以得出以下结论:

  • 父类静态部分:首先是父类的静态方法method()被调用,输出信息是“Parent method”。

  • 父类静态代码块:紧接着父类的静态代码块会被执行,输出信息是“Parent static block”。

  • 子类静态部分:在父类静态部分初始化完成后,子类的静态方法method()会被调用,输出信息是“Child method”。

  • 父类非静态部分:接着是父类的非静态代码块,输出信息是“Parent non-static block”。

  • 子类非静态部分:随后子类的非静态代码块会被执行,输出信息是“Child non-static block”。

  • 构造函数调用:最后是子类构造函数会被调用,输出信息是“Child constructor”。

  • 可以看到,在整个过程中,父类的静态成员始终会先于子类的静态成员被初始化,父类非静态成员的初始化也会在子类静态成员初始化之前完成。这种顺序是Java语言特有的设计,旨在确保类的完整性和一致性。

    五、总结

    通过对上述Class初始化过程的分析,我们可以清晰地看到Java在类加载过程中所遵循的初始化顺序。理解这一机制对于溶解实际开发中的一些Initialization问题颇有帮助。在编写继承关系的类时,合理地规划静态和非静态成员的位置,显著提升代码的可维护性和可靠性。希望以上对理解Java类的初始化顺序有所帮助。

    转载地址:http://yjryk.baihongyu.com/

    你可能感兴趣的文章
    pair的用法
    查看>>
    javaWeb服务详解(含源代码,测试通过,注释) ——Emp的Dao层
    查看>>
    echarts 基本图表开发小结
    查看>>
    TreeSet、TreeMap
    查看>>
    JVM内存模型
    查看>>
    可变长度参数
    查看>>
    GitHub上传时,项目在已有文档时直接push出现错误解决方案
    查看>>
    嵌入式系统试题库(CSU)
    查看>>
    00010.02最基础客户信息管理软件(意义类的小项目,练习基础,不涉及数据库)
    查看>>
    00013.05 字符串比较
    查看>>
    SpringCloud-Eureka报错 Error creating bean with name解决
    查看>>
    UE4 错误列表 error码(只记录我遇到的情况,持续添加,未完成)
    查看>>
    cmd编译.java文件 : java:720: 错误: 编码GBK的不可映射字符 Why ? ? ? ?
    查看>>
    Android 架构组件 – 让天下没有难做的 App
    查看>>
    能解决数据可视化大屏需求的3款可视化工具
    查看>>
    第01问:MySQL 一次 insert 刷几次盘?
    查看>>
    Android 开发常用的工具类(更新ing)
    查看>>
    Python爬虫训练:爬取酷燃网视频数据
    查看>>
    解决微信小程序项目导入的问题:app.json 未找到、 __wxConfig is not defined
    查看>>
    非迅捷|PDF、Word、PPT、Excel、图片等互相在线转换:免费、简单、快速、零错误、无套路
    查看>>