5、一个类中的各个元素的加载、初始化顺序是怎样的?

光储微电网混合储能系统的控制策略 随着社会生产力的不断提高,对不可再生资源的大量消耗,人们已经意识到发展可再生能源的重要性,因此微电网技术作为再生能源利用的有效形式被快速发展。蓄电池容量无限大是传统光储微电网混合储能系统控制策略一种理想形式,但实际上蓄电池的容量是有限度的,传统控制策略在蓄电池剩余电量达到阖值时将无法正常使用,由此提出了光储微电网混合储能系统的新型控制策略,又结合实际情况,对开关进行了改进,利用开关与二极管并联,使其拥有四种工作状态,当储能元件剩余电量达到阈值时,可自动恢复电量降低成本,提高并输出电池电能质量。 阅读详情

在 Java 中,一个类的加载、链接、初始化过程由 JVM 严格按照规范执行,而类内部各元素(静态成员、实例成员、构造器等)的初始化顺序也有明确规则。理解这一顺序对掌握对象创建机制、避免初始化错误(如空指针、未定义行为)至关重要。


一、整体流程:类的生命周期(JVM 层面)

Java 类的生命周期分为以下阶段:

  1. 加载(Loading)

    • 通过类加载器(ClassLoader)将 .class 字节码文件读入内存;
    • 生成 java.lang.Class 对象。
  2. 链接(Linking)

    • 验证(Verification):确保字节码安全、合法;
    • 准备(Preparation):为静态变量分配内存并设置默认初始值(如 0、null、false),不执行初始化代码;
    • 解析(Resolution):将符号引用转为直接引用(可选,部分在初始化后进行)。
  3. 初始化(Initialization)

    • 执行静态初始化代码:包括静态变量显式赋值和静态代码块(static {});
    • 这是类初始化阶段,也是我们关注“初始化顺序”的核心。

✅ 触发类初始化的时机(JLS §12.4.1):

  • 创建类的实例(new);
  • 访问类的静态非常量字段(static final 基本类型/字符串字面量除外);
  • 调用类的静态方法;
  • 使用反射(如 Class.forName());
  • 初始化子类时,先初始化父类;
  • 启动类(含 main 方法的类)。

二、类内部元素的初始化顺序(重点)

当一个类被初始化(或创建对象)时,其内部元素按以下严格顺序执行:

📌 1. 父类优先原则

先初始化父类,再初始化子类(递归至 Object)。

📌 2. 静态成员先于实例成员

静态内容只初始化一次(类加载时),实例内容每次创建对象时初始化。

📌 3. 同类中按代码书写顺序执行


✅ 完整初始化顺序(创建对象时)

假设有一个子类 Child 继承自 Parent,两者均包含各类成员:

1. 父类 Parent 的静态变量(默认值 → 显式赋值)
2. 父类 Parent 的静态代码块(static {})
3. 子类 Child 的静态变量(默认值 → 显式赋值)
4. 子类 Child 的静态代码块(static {})
   ↓
5. 父类 Parent 的实例变量(默认值 → 显式赋值)
6. 父类 Parent 的实例代码块({})
7. 父类 Parent 的构造器
8. 子类 Child 的实例变量(默认值 → 显式赋值)
9. 子类 Child 的实例代码块({})
10. 子类 Child 的构造器

💡 关键点:

  • 静态内容在类首次主动使用时初始化一次;
  • 实例内容在每次 new 对象时执行;
  • 变量赋值与代码块按源码从上到下顺序执行。

三、详细示例与中文注释说明

示例代码:展示完整初始化顺序

// 父类
class Parent {
    // 1. 静态变量(准备阶段设为 null,初始化阶段赋值)
    static String parentStaticField = initParentStaticField();

    // 2. 静态代码块
    static {
        System.out.println("【父类】静态代码块执行");
    }

    // 5. 实例变量
    String parentInstanceField = initParentInstanceField();

    // 6. 实例代码块
    {
        System.out.println("【父类】实例代码块执行");
    }

    // 7. 构造器
    public Parent() {
        System.out.println("【父类】构造器执行");
    }

    // 辅助方法(用于观察初始化时机)
    static String initParentStaticField() {
        System.out.println("【父类】静态变量初始化");
        return "Parent Static";
    }

    String initParentInstanceField() {
        System.out.println("【父类】实例变量初始化");
        return "Parent Instance";
    }
}

// 子类
class Child extends Parent {
    // 3. 静态变量
    static String childStaticField = initChildStaticField();

    // 4. 静态代码块
    static {
        System.out.println("【子类】静态代码块执行");
    }

    // 8. 实例变量
    String childInstanceField = initChildInstanceField();

    // 9. 实例代码块
    {
        System.out.println("【子类】实例代码块执行");
    }

    // 10. 构造器
    public Child() {
        System.out.println("【子类】构造器执行");
    }

    static String initChildStaticField() {
        System.out.println("【子类】静态变量初始化");
        return "Child Static";
    }

    String initChildInstanceField() {
        System.out.println("【子类】实例变量初始化");
        return "Child Instance";
    }
}

// 测试类
public class InitializationOrderDemo {
    public static void main(String[] args) {
        System.out.println("=== 第一次创建 Child 对象 ===");
        new Child();

        System.out.println("\n=== 第二次创建 Child 对象 ===");
        new Child(); // 静态部分不会重复执行
    }
}

🔍 输出结果分析:

=== 第一次创建 Child 对象 ===
【父类】静态变量初始化
【父类】静态代码块执行
【子类】静态变量初始化
【子类】静态代码块执行
【父类】实例变量初始化
【父类】实例代码块执行
【父类】构造器执行
【子类】实例变量初始化
【子类】实例代码块执行
【子类】构造器执行

=== 第二次创建 Child 对象 ===
【父类】实例变量初始化
【父类】实例代码块执行
【父类】构造器执行
【子类】实例变量初始化
【子类】实例代码块执行
【子类】构造器执行

✅ 结论:

  • 静态部分(1-4)仅在首次使用类时执行一次;
  • 实例部分(5-10)每次 new 对象都执行;
  • 父类始终先于子类初始化。

四、特殊情况说明

4.1 静态常量(static final)不触发类初始化

class Constants {
    public static final int VALUE = 100; // 编译期常量
    static {
        System.out.println("Constants 类被初始化!");
    }
}

public class ConstantDemo {
    public static void main(String[] args) {
        System.out.println(Constants.VALUE); // 直接输出 100,不触发初始化!
    }
}

输出:100(无“Constants 类被初始化!”)
原因:VALUE 是编译期常量,值已内联到调用处,无需加载 Constants 类。

4.2 静态变量赋值 vs 静态代码块

class OrderTest {
    static int a = 1;
    static {
        a = 2;
    }
    static int b = a; // b = 2

    public static void main(String[] args) {
        System.out.println("a=" + a + ", b=" + b); // a=2, b=2
    }
}

说明:静态变量和静态代码块按源码顺序执行。

4.3 构造器中的 super() 调用

  • 子类构造器第一行隐式或显式调用 super();
  • 因此父类构造器总是在子类构造器之前执行。

五、总结:初始化顺序口诀

“父静子静,父实子实;
变量代码块,顺序不能乱;
构造最后来,super 在最前。”

阶段元素执行时机次数
静态初始化父类静态变量/代码块类首次主动使用时1 次
子类静态变量/代码块同上1 次
实例初始化父类实例变量/代码块每次 new 对象时每次
父类构造器同上每次
子类实例变量/代码块同上每次
子类构造器同上每次

六、实际应用建议

  1. 避免在静态初始化中依赖未初始化的静态变量;
  2. 不要在父类构造器中调用可能被子类重写的方法(此时子类尚未初始化,可能导致空指针);
  3. 使用 final 字段确保初始化完成后不可变;
  4. 理解类初始化时机,避免 ClassNotFoundException 或 NoClassDefFoundError。

掌握类初始化顺序,是深入理解 Java 对象模型、JVM 机制和编写健壮代码的基础。

2023华为od机试【最小循环子数组】C++ 2023华为od机试【最小循环子数组】C++ 给定一个由若干整数组成的数组nums,请检查数组是否是由某个子数组重复循环拼接而成,请输出这个最小的子数组。 阅读详情

相关推荐

ADS 2024 Circuit Envelope 仿真:3步配置调制源,分析5G NR EVM与ACPR

本文详细介绍了ADS 2024 Circuit Envelope仿真技术在5G NR调制源配置与关键指标分析中的应用。通过3步配置调制源,工程师可以高效评估EVM与ACPR等关键指标,特别适用于功放设计中的非线性效应诊断。文章还提供了优化仿真设置和精确提取EVM、ACPR的实用方法,助力5G射频前端设计。

weixin_28559803的博客 380

java类的初始化顺序

类的初始化顺序是: 1、初始化父类中的静态成员变量和静态代码块。 2、初始化子类中的静态成员变量和静态代码块。  3、初始化父类中的普通成员变量和代码块,在执行父类中的构造方法。 4、初始化子类中的普通成员变量和代码块,在执行子类中的构造方法。

码农也有梦想 443

python机器人编程——用pytorch实现六轴机械臂的正向和逆向数值解算,及python算法解析

前面对六轴(或多轴)机械臂进行了一些研究,特别是利用几何进行简化,实现逆解,来完成比较简单的搬用任务。然而,如果需要比较精确的操作任务,可能需要更加复杂的机械臂解算。其中比较复杂的是数值解算,这种解算往往涉及到比较复杂的机器人运动等原理知识,比较难以上手。但是,python的生态挺全面,已经有很多牛人实现了数值解法,但是去看他们的代码,还是觉得费劲。此外,随着深度神经网络的兴起,很多是用建立深度学习神经网络,去利用机械臂输入输出的大数据,训练机械臂的控制模型,这个上手也比较慢。

JAMES费的空间 5791

类的初始化顺序

一、类初始化顺序 1、父类–静态变量 2、父类–静态初始化块 3、子类–静态变量 4、子类–静态初始化块 5、父类–变量 6、父类–初始化块 7、父类–构造器 8、子类–变量 9、子类–初始化块 10、子类–构造器 二、顺序规律 1、父类->子类 2、静态变量->静态初始化块->变量->初始化块->构造器->普通方法 ...

u012648455的博客 668

伺服驱动器485通信

485通信使用方法,485通信在上位机和伺服驱动器之间的应用,根据需要驱动电机旋转。

haipi511715316的博客 1万+

从零到一:NI USB-8506 LIN通讯的驱动安装与硬件调试全攻略

本文详细介绍了NI USB-8506 LIN通讯设备的驱动安装与硬件调试全流程,包括硬件准备、驱动下载与配置、NI MAX设置及常见问题解决方案。通过实战应用与性能优化技巧,帮助用户快速掌握LIN通讯技术,适用于车载数据记录和自动化测试等场景。

weixin_28273593的博客 924

Java类的初始化顺序

类初始化顺序遵循以下三个原则(优先级依次递减)1、静态对象(变量)优先于非静态对象(变量)初始化,其中静态对象(变量)只初始化一次,而非静态对象(变量)可能会初始化多次;2、父类优先于子类初始化;3、成员变量按照定义先后顺序进行初始化;例如:静态变量、非静态变量、静态代码块、非静态代码块、构造函数、父类、子类等。

weixin_62988359的博客 4919

Python连接高斯数据库踩坑实录:从SASL报错到SSL安全连接的完整指南

本文详细记录了Python连接高斯数据库时遇到的SASL authentication报错及其解决方法。通过剖析SASL认证机制,对比了修改数据库配置、使用官方驱动等方案的利弊,并重点提供了通过自动化脚本生成SSL证书,实现安全、免密连接的完整指南,帮助开发者彻底解决连接难题。

weixin_28340315的博客 438

类初始化流程

一、类的初始化顺序(静态变量、静态初始化块:决于它们在类中出现的先后顺序)>(变量、初始化块:决于它们在类中出现的先后顺序)>构造器 原理: 1、加载类信息。在实例化对象之前,类的装载器会找到需要加载的类class文件,进行类的加载(有父类的会先加载父类),一旦加载到最根上的基类,就会对基类的静态变量和静态初始化块进行初始化; 2、当所有类信息加载完毕就会执行main()主方法,然后执...

l1394049664的博客 4186

uniapp实现app版本发现新版本后,自动更新

app实现自动更新

oldolder的博客 1282

如何在 VMware Workstation 虚拟机中利用 Nvidia 显卡的硬件加速功能

本文详细介绍了在VMware Workstation虚拟机中配置Nvidia显卡硬件加速的完整流程。重点包括:检查硬件兼容性、安装显卡驱动、编辑VMware配置文件启用PCI直通功能(需修改config.ini文件参数)、为虚拟机分配PCI设备等关键步骤。文章特别强调了配置注意事项,如系统资源需求、BIOS设置要求、驱动兼容性等问题,并建议操作前备份数据。通过此方法可实现虚拟机对Nvidia显卡的直接调用,适用于需要GPU加速的计算场景。

qq_39777550的博客 6696

JAVA类初始化顺序总结

类的初始化 {#articleHeader1} 初始化顺序 首先来看下,当一个类从main入口方法,对于静态变量、静态初始化块、变量、初始化块、构造器,它们的初始化顺序: public class ClassLoadTest { private static User user = new User(); static { System.err.println("static code block...

luoyoub的博客 1万+

EtherCAT主站SOEM -- 1 -- SOEM之ethercattype.h文件分析

“ethercattype.h” 文件用于支持 EtherCAT 网络通信,提供了各种类型定义和宏,以便开发者更轻松地开发 EtherCAT 相关应用程序。这些定义包括数据类型、命令类型、状态类型和错误类型,以支持 EtherCAT 通信。根据具体应用需求,还可以调整一些超时和帧长度设置。这些定义用于处理函数调用的结果,如 EC_NOFRAME(没有帧返回)、EC_ERROR(一般错误)、EC_TIMEOUT(请求超时)等。这些定义用于处理 EtherCAT 命令,例如 EC_CMD_APRD(自动递增读取

常驻客栈的博客--嵌入式EtherCAT 2714

类的初始化顺序、类加载顺序

1.类的加载顺序:.java源文件(磁盘) -> javac编译器 -> .class文件(磁盘) -> java解释器------>JVM内存 2.类的加载(加载.class文件) 1)通过一个类的全限定名获取定义此类的二进制字节流。 2)将这个字节流所代表的静态存储结构转换为方法区运行时数据结构。 ​ 3)在内存中生成一个代表这个类的java.lang.Class对象,作为方法区这个类的各种数据的访问的入口。 3.类加载器:先识别字节码文件 文件类型:后缀名+魔数

qq_43558952的博客 985

老版QQ原生表情gif动态

这是老版的QQ表情,不过全是动态的的,Windows照片查看器是不会动的,可以右击用浏览器打开查看,再说一遍是老版的,只是分享给宁愿用老版也要动态的人。

TMS_WebGMaps_1.9.8.0_Full_Source

TMS_WebGMaps_1.9.8.0_Full_Source 全源码 delphi cbuilder

类的加载顺序

初始化顺序: 1.先静态后非静态 先初始化静态的成员变量,在类第一次被使用时初始化一次 2.先声明后赋值 所有声明的成员变量先获得默认值(基本类型对应基本类型默认值,引用类型为null),然后执行等号后的赋值 3.先属性后方法 先执行属性定义处的初始化,然后执行方法的初始化(构造块先于构造方法) 4.先父类后子类 继承时候先初始化父类成员,后子类成员 所以通常...

qq_25210753的博客 2736

win10 跳过U8环境检测的IE WebControls.rar

win10 安装u8的时候 提示IE WebControls 不通过,这个工具可以欺骗u8的检查。 跳过U8环境检测的IE WebControls。提示导入失败后,重新检测通过。

类加载顺序和类初始化顺序

i)、java编译器加载类的二进制字节流文件(.class文件),如果该类有基类,向上一直加载到根基类(不管基类是否使用都会加载)。顺序是:父类静态优先--子类静态---父类的所有非静态(块和构造器)----子类的所有非静态(块和构造器)1.父类的静态代码块和父类的静态变量初始化(至于他俩的先后顺序完全是由他们在代码中的顺序所决定的)。类的加载和链接只执行一次,故static成员也只加载一次,作为类所拥有、类的所有实例共享。类加载器采用双亲委托(自底向上查询)来避免重复加载类,而加载顺序却是自顶向下的。

weixin_47796247的博客 809

Java 理解类的加载机制 类加载顺序 类初始化过程 实例初始化过程

一、代码如下 1、创建一个Father类,包含实例变量、静态变量、静态代码块、构造方法、构造代码块、实例方法、静态方法 **@Description: 理解类的加载机制 * @version v1.0 * @author w * @date 2021年8月14日上午8:58:24 */ public class Father { // 实例变量 private int i = test(); // 静态变量 private static int x = metho...

HaHa_Sir的博客 2664

Java 对象初始化和类初始化的区别、new一个对象的详细过程、类加载、类初始化、实例初始化

Java 初始化的深认知(第二篇)Java 类初始化和对象初始化明解Java中new一个对象的详细过程,JVM执行了那些操作new一个对象的详细过程什么时候需要初始化一个类获得类的资源初始化对象 Dog dog = new Dog()创建一个对象时jvm在干什么:Java 对象的使用:对对象的访问定位类加载过程(第一次使用该类)双亲委派机制更多知识 首先,大家看一下这段代码的执行顺序,你是否理解的如注释所写: //父类Animal class Animal { /*8、执行初始化*/ pri

qq_42603181的博客 3064

Java类、实例的初始化顺序

阿里巴巴2013校园招聘笔试题倒数第二题:java类、对象初始化顺序的分析

biaobiaoqi的老博客 1万+

java加深理解类的初始化顺序

Java虚拟机怎么加载类,决定了我们书写代码的执行顺序。Python也有模块的加载概念,其实任何编程语言,加载顺序都是存在的,一起学习Java的类的加载顺序,大概分为3种类型的加载1、单个类的加载2、父类、子类的加载3、组合类的加载理解了类的加载顺序,对阅读Java源码会有极大的帮助,所以请一定好好学习噢。

王员外的博客 1005

类装载(加载),懒加载与初始化,类加载顺序

类装载 在任何时刻,第一次访问某类,都会执行类装载 访问包括三种情况: 使用某类的static方法 访问某类的static属性 构造某类的对象 声明没有初始化的引用Administrator admin;,并不会导致类装载(This is lazy load) 一个类的装载只会执行一次 类装载的工作清单: 加载.class字节码文件:根据包语法决定的路径找到.class文件并加载 为static属性分配存储空间并全部置为默认值(Q:默认值是多少) 装载父类:如果这个类有父类,且父类还没有被装载过,则先装载它

笔记别偷看 1521

Java类的加载顺序

1、有继承关系的加载顺序 关于关键字static,大家 都知道它是静态的,相当于一个全局变量,也就是这个属性或者方法是可以通过类来访问,当class文件被加载进内存,开始初始化的时候,被static修饰的变量或者方法即被分配了内存,而其他变量是在对象被创建后,才被分配了内存的。 所以在类中,加载顺序为: 1.首先加载父类的静态字段或者静态语句块 2.子类的静态字段或静态语句块 3.父类普通变量以及语句块 4.父类构造方法被加载 5.子类变量或者语句块被加载 6.子类构造方法被加载 父类代码: public

FanGer的博客 4510

Java 类和对象的初始化过程及初始化顺序

静态的属于全局静态区,这个部分独立存在,不管是成员还是块,都是静态的,大家地位相等,先到先得。   然后是成员初始化,这个部分在类的构造函数前初始化,因为编译器(或者设计者)可能认为构造函数调用了这个成员变量,所以在其前初始化了。或者说是成员自己有自己的能力来初始化自己,不用构造函数来管,这部分属于能力比较强的,虽然没有静态的地位高,但是,还是能自给自足的一部分团体。   最后才构造函

xyjikl 4671

Java类加载机制、初始化顺序

目录 一、类加载过程 1.1、加载 1.2、链接 1.3、初始化 二、类初始化时机 2.1、只有在对类主动使用的时候才会导致类的初始化,类的主动使用包括以下六种: 2.2、子类和父类初始化顺序(针对属性、代码块、构造方法) 三、类的生命周期 四、类加载机制 4.1、类加载器 4.2、类加载机制的分类 4.3、关于双亲委派机制 一、类加载过程 类加载过程分为加载、链...

LeeeeC的博客 1195

java类加载阶段与初始化顺序

一、类加载概述 在JVM执行我们写好的代码的过程中,具体是在代码中用到这个类的时候将“.class”文件加载进JVM内存里,类的加载到使用具体经过下面这几个过程: 加载 -> 验证 -> 准备 -> 解析 -> 初始化 -> 使用 -> 卸载。 各个将阶段的任务描述: 二、类的初始化顺序 Java类加载机制中最重要的就是程序初始化过程,其中包含了静态资源,非静态资源,父类子类,构造方法之间的执行顺序。 首先通过一个例子来分析java代码的执行顺序:

codedot 757

从类加载过程分析类的初始化顺序

虚拟机把描述类的数据从Class文件加载到内存,并对数据进行校验,转换解析,和初始化,最终形成可以被虚拟机直接使用的Java类型,这就是虚拟机的类加载机制。 类加载时机 类加载时机分为七个阶段,分别为加载->验证->准备->解析->初始化->使用->卸载。 加载,验证,准备,初始化,卸载这5个阶段的顺序是确定的,也就是说一个类的初始化完成,那么这个类必须经...

qq_37548474的博客 256
上一篇: 4、Java 面向对象编程(OOP)详解
下一篇: MyBatis-Plus-Generator 详细使用指南:基于 Spring Boot + Freemarker 模板引擎的代码生成器
龙茶清欢
博客等级 码龄7年 3720粉丝 375原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

龙茶清欢

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值