Java 代码块

一、 静态代码块 (Static Block)

  1. 格式

    java 复制代码
    static {
        // 初始化逻辑
    }
  2. 执行时机与顺序

    • 在类加载到内存的"初始化阶段"执行
    • 优先于实例代码块和构造器执行
    • 若存在多个静态代码块,按照在代码中定义的先后顺序依次执行
    • 父类的静态代码块优先于子类的静态代码块执行
  3. 作用与典型应用场景

    • 对静态成员变量进行复杂初始化(无法通过简单赋值完成时)
    • 加载配置文件、读取外部资源或建立数据库连接池等全局一次性操作
    • 注册驱动(如JDBC中的 Class.forName 旧式写法)
    • 执行仅需运行一次的校验或日志记录
  4. 注意事项

    • 只能访问静态成员(静态变量、静态方法),不能直接访问实例成员
    • 不能使用 thissuper 关键字
    • 不能抛出受检异常(Checked Exception),除非在内部捕获处理;若发生未捕获的运行时异常,会导致类加载失败,抛出 ExceptionInInitializerError
    • 即使不创建对象,只要类被主动使用(如调用静态方法、访问静态字段),静态代码块也会执行

二、 实例代码块 (Instance Initializer Block)

  1. 格式

    java 复制代码
    {
        // 初始化逻辑
    }
  2. 执行时机与顺序

    • 每次调用构造器创建对象时执行
    • 执行顺序:父类静态代码块 -> 子类静态代码块 -> 父类实例代码块 -> 父类构造器 -> 子类实例代码块 -> 子类构造器
    • 若存在多个实例代码块,按照定义顺序依次执行
    • 无论调用哪个重载构造器,实例代码块都会执行
  3. 作用与典型应用场景

    • 提取多个构造器中的公共初始化逻辑,避免代码重复
    • 对实例变量进行复杂初始化,尤其是当初始化逻辑相同但构造器参数不同时
    • 在匿名内部类中执行初始化操作(因为匿名内部类没有命名构造器)
  4. 注意事项

    • 可以访问静态成员和实例成员
    • 可以使用 this 关键字
    • 不能抛出受检异常,除非在内部处理或在所有构造器的声明中都包含该异常
    • 若仅在某个特定构造器中需要某段初始化逻辑,应直接写在构造器内,而非实例代码块中,以免在其他构造器调用时产生不必要的副作用

三、 完整执行顺序总结

假设存在继承关系,创建子类对象时的完整执行流程如下:

  1. 父类静态代码块(仅首次加载时)
  2. 子类静态代码块(仅首次加载时)
  3. 父类实例代码块
  4. 父类构造器
  5. 子类实例代码块
  6. 子类构造器

记忆口诀:静态先于实例,父类先于子类,代码块先于构造器


四、 对比总结表

特性 静态代码块 实例代码块
修饰符 static
执行次数 类生命周期内仅一次 每创建一个对象执行一次
执行时机 类加载初始化阶段 对象创建时,构造器之前
可访问成员 仅静态成员 静态成员 + 实例成员
this/super 不可用 可用
主要用途 类级别一次性初始化 对象级别公共初始化 / 匿名类初始化

五、 补充说明

  • 局部代码块 :在方法内部定义的 { },用于限制变量作用域,与方法内普通语句无异,现代Java开发中极少使用,了解即可
  • 序列化场景:实例代码块在反序列化过程中不会被执行(反序列化不调用构造器),若依赖实例代码块进行关键初始化,需注意此行为差异
  • 实践:优先使用显式构造器和静态工厂方法进行初始化,代码块仅在确实能减少重复代码或处理匿名类等特殊场景时使用,避免滥用导致代码可读性下降

相关推荐
小羊没烦恼!1 天前
微服务化的基石——持续集成
java·大数据·word·powerpoint·.net
俊昭喜喜里1 天前
java中的继承和多态的区别
java
小羊没烦恼!1 天前
初探性能优化——2个月到4小时的性能提升
java·开发语言·windows·算法·c#
譕痕1 天前
JSONObject与JSONArray封装数据格式区别
java·json
胡写代码1 天前
别再前后端各写一套表单校验了
java·后端
小鱼能吃糖1 天前
缺陷修复总览 · mall电商项目:5类缺陷,1个病根,4个业务域
java·电商
此时不提桶,更待何时1 天前
01-06-A-JVM排查实战详解
java·jvm
伞伞悦读1 天前
【第38期】Python 模块与包详解:import、from、模块搜索路径、包结构和 __init__
开发语言·python
vipxieliang1 天前
ValidX 在 DDD 领域驱动设计中的实践
java·spring boot
C语言小火车1 天前
C/C++ 为什么需要编译器?
开发语言·c++