Java 类加载与代码块执行顺序详解

简介: 本文详解Java中静态代码块、实例初始化块、构造器及局部代码块的执行顺序。通过示例分析,揭示类加载与对象创建时的生命周期机制,并总结“静→局→初→构”口诀,帮助开发者合理初始化资源,避免常见错误,提升代码健壮性与可读性。


在 Java 中,不同类型的代码块(静态代码块、实例初始化块、构造器)以及局部代码块的执行顺序,直接关系到对象创建和类加载的生命周期。通过分析以下示例,我们可以清晰掌握其加载机制。


🧪 示例代码回顾

public class CodeBlockDemo {
    { 
        System.out.println("初始化代码"); // 实例初始化块
    }
    CodeBlockDemo() {
        System.out.println("构造器");
    }   
    static {
        System.out.println("静态代码块"); // 静态代码块
    }
    
    public static void main(String[] args) {
        {
            int a = 10;
            System.out.println("局部代码块"); // 局部代码块
        }
        new CodeBlockDemo();
        new CodeBlockDemo();
        new CodeBlockDemo();
    }
}

输出结果:

静态代码块
局部代码块
初始化代码
构造器
初始化代码
构造器
初始化代码
构造器

🔍 执行顺序解析

1. 静态代码块(static {})
  • 触发时机:类首次被加载(ClassLoader 加载类时)
  • 执行次数仅一次,无论创建多少对象
  • 优先级最高,在 main 方法之前执行
  • ✅ 本例中:程序启动 → 加载 CodeBlockDemo 类 → 执行静态代码块 → 输出 "静态代码块"

💡 静态代码块常用于类级别的初始化,如加载驱动、读取配置等。


2. 局部代码块(方法内的 {}
  • 作用域:仅限于所在方法(此处是 main 方法)
  • 执行时机:按代码顺序执行
  • ✅ 本例中:进入 main 后立即执行 → 输出 "局部代码块"

⚠️ 局部代码块与类加载无关,纯粹是语法糖,用于限制变量作用域。


3. 实例初始化块(非静态 {}
  • 触发时机每次创建对象时,在调用构造器之前执行
  • 作用:为所有构造器提供公共初始化逻辑
  • ✅ 每次 new CodeBlockDemo() 时:
  • 先执行 "初始化代码"
  • 再执行 "构造器"

📌 执行顺序:实例初始化块 → 构造器


4. 构造器(Constructor)
  • 在实例初始化块之后执行
  • 用于完成对象的最终初始化

📋 总结:完整执行优先级

代码块类型 执行时机 执行次数 说明
静态代码块 类加载时 1 次 最先执行,早于 main
局部代码块 方法内按顺序执行 按代码路径 与类加载无关
实例初始化块 每次 new 对象时(构造前) N 次 在构造器之前
构造器 每次 new 对象时 N 次 最后完成对象构建

口诀记忆

静(静态)→ 局(局部)→ 初(初始化块)→ 构(构造器)


💡 实际应用建议

  • 使用 静态代码块 初始化全局资源(如数据库连接池、配置加载);
  • 使用 实例初始化块 替代重复的构造器初始化逻辑;
  • 避免在静态块中做耗时操作,会延迟类加载,影响启动性能;
  • 局部代码块 可用于临时变量隔离,提升代码可读性。

理解这些执行顺序,有助于精准控制初始化逻辑,避免因顺序错误导致的空指针或状态不一致问题。


相关文章
|
Java 开发者
重学Java基础篇—Java类加载顺序深度解析
本文全面解析Java类的生命周期与加载顺序,涵盖从加载到卸载的七个阶段,并深入探讨初始化阶段的执行规则。通过单类、继承体系的实例分析,明确静态与实例初始化的顺序。同时,列举六种触发初始化的场景及特殊场景处理(如接口初始化)。提供类加载完整流程图与记忆口诀,助于理解复杂初始化逻辑。此外,针对空指针异常等问题提出排查方案,并给出最佳实践建议,帮助开发者优化程序设计、定位BUG及理解框架机制。最后扩展讲解类加载器层次与双亲委派机制,为深入研究奠定基础。
565 0
|
XML 应用服务中间件 数据格式
windows下Tomcat8.0解压版安装并配置环境变量
windows下Tomcat8.0解压版安装并配置环境变量
1669 0
|
Kubernetes 容器 Perl
k8s查看日志命令—2023.02
k8s查看日志命令—2023.02
695 0
|
7月前
|
存储 安全
3.OAuth2.0四种授权模式
本文详解OAuth2授权码模式流程:A服务客户端通过B服务认证服务,经用户授权获取授权码,再换取访问令牌,从而安全调用B服务资源。该模式安全性高,广泛应用于第三方登录场景。
3.OAuth2.0四种授权模式
|
XML Java 数据库连接
Mybatis一对一,一对多关联查询
## MyBatis一对一、一对多关联查询详解 MyBatis是一款优秀的持久层框架,提供了灵活的SQL映射功能,支持复杂的数据库操作。本文将详细介绍MyBatis中一对一和一对多关联查询的实现。 ### 一对一关联查询 一对一关联关系指的是一个表中的一条记录与另一个表中的一条记录相关联。例如,一个用户有一个地址信息。 #### 数据库表设计 假设有两个表:`user`和 `address`。 ``` CREATE TABLE user ( id INT PRIMARY KEY, name VARCHAR(50) ); CREATE TABLE address
615 18
|
算法 NoSQL Redis
分布式锁—4.Redisson的联锁和红锁
Redisson的MultiLock和RedLock机制为分布式锁提供了强大的支持。MultiLock允许一次性锁定多个资源,确保在更新这些资源时不会被其他线程干扰。它通过将多个锁合并为一个大锁,统一进行加锁和释放操作。RedissonMultiLock的实现通过遍历所有锁并尝试加锁,若在超时时间内无法获取所有锁,则释放已获取的锁并重试。 RedLock算法则基于多个Redis节点的加锁机制,确保在大多数节点上加锁成功即可。RedissonRedLock通过重载MultiLock的failedLocksLi
816 10
Java—多线程实现生产消费者
本文介绍了多线程实现生产消费者模式的三个版本。Version1包含四个类:`Producer`(生产者)、`Consumer`(消费者)、`Resource`(公共资源)和`TestMain`(测试类)。通过`synchronized`和`wait/notify`机制控制线程同步,但存在多个生产者或消费者时可能出现多次生产和消费的问题。 Version2将`if`改为`while`,解决了多次生产和消费的问题,但仍可能因`notify()`随机唤醒线程而导致死锁。因此,引入了`notifyAll()`来唤醒所有等待线程,但这会带来性能问题。
403 1
Java—多线程实现生产消费者
|
Java 开发者 数据格式
【Java笔记+踩坑】SpringBoot基础4——原理篇
bean的8种加载方式,自动配置原理、自定义starter开发、SpringBoot程序启动流程解析
【Java笔记+踩坑】SpringBoot基础4——原理篇
|
Java Spring
Spring框架: Spring Bean的生命周期是什么样的?
Spring Bean经历实例化、属性赋值、初始化和销毁四个阶段: 1. 反射创建Bean实例。 2. 注入属性值通过setter方法。 3. 执行用户定义的初始化方法(init-method)。 4. 不再需要时,调用销毁方法(destroy-method)。生命周期中,自动操作与用户扩展点并存。
534 0

热门文章

最新文章