文章目录
- 一、什么是静态代码块?
- 二、静态代码块的执行时机
- 类什么时候被加载?
- 执行顺序示例
- 三、静态代码块 vs 构造代码块
- 构造代码块(实例代码块)
- 对比表
- 四、多个静态代码块的执行顺序
- 同一个类中
- 父类与子类的执行顺序
- 五、静态代码块的典型使用场景
- 初始化静态变量
- 加载资源或驱动
- 复杂初始化逻辑
- 六、静态代码块中的注意事项(重点)
- 不能使用 `return`
- 不能访问实例变量和实例方法
- 异常必须处理
- 七、静态代码块与静态变量初始化顺序
- 八、JVM 角度理解静态代码块
- 九、面试高频问题总结
- ❓ 静态代码块执行几次?
- ❓ 能否继承?
- ❓ 静态代码块能访问非静态成员吗?
- ❓ static 代码块和 static 方法的区别?
一、什么是静态代码块?
在 Java 中,static关键字不仅可以修饰变量和方法,还可以修饰代码块。
静态代码块(static block)是类加载阶段执行的一段代码,常用于类级别的初始化操作。
本文将从语法、执行时机、底层原理、使用场景、常见陷阱以及面试要点等方面,简单介绍Java 的静态代码块。如有问题,欢迎在评论区留言( •̀ ω •́ )✧
静态代码块是使用static {}定义的代码块:
static{// 静态初始化代码}特点:
- 属于类本身
- 在类加载时执行
- 只执行一次
- 早于任何对象创建执行
静态代码块是 Java 在“类加载阶段”留给开发者的初始化钩子。
二、静态代码块的执行时机
类什么时候被加载?
以下情况会触发类加载:
- 使用
new创建对象 - 访问类的静态变量
- 调用类的静态方法
- 反射加载类(
Class.forName) - JVM 启动时加载主类
执行顺序示例
classTest{static{System.out.println("静态代码块执行");}publicTest(){System.out.println("构造方法执行");}}publicclassMain{publicstaticvoidmain(String[]args){newTest();}}输出结果:
静态代码块执行 构造方法执行📌 说明:
静态代码块 → 构造方法
三、静态代码块 vs 构造代码块
构造代码块(实例代码块)
{System.out.println("构造代码块");}对比表
| 对比项 | 静态代码块 | 构造代码块 |
|---|---|---|
| 关键字 | static | 无 |
| 执行时机 | 类加载时 | 创建对象时 |
| 执行次数 | 一次 | 每次创建对象 |
| 作用对象 | 类 | 实例 |
| 常见用途 | 初始化静态资源 | 初始化实例数据 |
四、多个静态代码块的执行顺序
同一个类中
classDemo{static{System.out.println("static block 1");}static{System.out.println("static block 2");}}输出:
static block 1 static block 2📌按书写顺序执行
父类与子类的执行顺序
classParent{static{System.out.println("父类静态代码块");}}classChildextendsParent{static{System.out.println("子类静态代码块");}}publicclassTest{publicstaticvoidmain(String[]args){newChild();}}输出:
父类静态代码块 子类静态代码块📌 顺序总结:
父类静态代码块 → 子类静态代码块 → 构造代码块 → 构造方法五、静态代码块的典型使用场景
初始化静态变量
classConfig{staticMap<String,String>map;static{map=newHashMap<>();map.put("url","localhost");map.put("port","8080");}}加载资源或驱动
static{try{Class.forName("com.mysql.cj.jdbc.Driver");}catch(ClassNotFoundExceptione){e.printStackTrace();}}复杂初始化逻辑
当初始化逻辑较复杂,静态变量一行代码无法完成时,静态代码块非常合适。
六、静态代码块中的注意事项(重点)
不能使用return
static{return;// ❌ 编译错误}不能访问实例变量和实例方法
intx=10;static{System.out.println(x);// ❌}原因:
静态代码块执行时,对象尚未创建
异常必须处理
static{// 不能抛受检异常try{// risky code}catch(Exceptione){e.printStackTrace();}}七、静态代码块与静态变量初始化顺序
classOrderTest{staticinta=10;static{a=20;}staticintb=30;}执行后:
a==20b==30📌 规则:
按代码书写顺序执行
八、JVM 角度理解静态代码块
- 静态代码块在类初始化阶段( 方法)执行
- JVM 保证
<clinit>在多线程环境下只执行一次 - 天然线程安全
九、面试高频问题总结
❓ 静态代码块执行几次?
一次(类加载时)
❓ 能否继承?
不继承,但会先执行父类静态代码块
❓ 静态代码块能访问非静态成员吗?
不能
❓ static 代码块和 static 方法的区别?
static 方法可多次调用,static 代码块只执行一次
如果还没理解,可参考
静态代码块、构造代码块、构造方法的执行顺序- bilibili.com
Java静态代码块深度剖析:机制、特性与最佳实践 - 稀土掘金