静态块先执行,顺序为:父类静态块→子类静态块→父类构造块→父类构造函数→子类构造块→子类构造函数;因静态块属类级别初始化,jvm仅在首次主动使用类时执行一次。

构造块和静态块谁先执行
静态块(static {})在类加载时执行,且只执行一次;构造块({})在每次创建对象时执行,在构造函数体之前运行。所以顺序是:父类静态块 → 子类静态块 → 父类构造块 → 父类构造函数 → 子类构造块 → 子类构造函数。
为什么静态块不随 new 出现而重复执行
因为静态块属于类级别初始化逻辑,由 JVM 在首次主动使用该类(比如 new、调用静态方法、访问静态字段等)时触发类加载和初始化阶段。之后再 new 多少次对象,都不会再次执行静态块。
常见错误现象:static {} 里写了日志却只看到一次输出,误以为没生效;或误把依赖实例状态的初始化逻辑(如读取用户输入)写进静态块,导致后续对象拿不到新值。
- 静态块适合做单例初始化、配置加载、驱动注册等一次性操作
- 不能访问非静态成员(编译报错:
non-static variable xxx cannot be referenced from a static context) - 多个静态块按源码顺序合并执行,中间插入变量声明不影响顺序
构造块和构造函数参数怎么配合用
构造块相当于所有构造函数共用的前置逻辑,适合提取重复初始化代码。但它无法接收参数,也不能做条件分支(比如根据传入参数决定是否初始化某字段)。
立即学习“Java免费学习笔记(深入)”;
使用场景举例:给每个对象都设置默认时间戳、初始化某个集合、打印统一创建日志。
容易踩的坑:
- 误以为构造块能替代带参构造函数——它没法拿到
this(...)或参数值 - 在构造块里调用可能被子类重写的方法(
override),此时子类字段尚未初始化,可能为null或默认值(典型空指针隐患) - 和构造函数体里的同名赋值冲突,比如构造块设了
name = "default",构造函数又设了name = inputName,后者会覆盖前者
嵌套类里的静态块和构造块还生效吗
生效,但要分清楚是哪个类的块。普通内部类(非 static)不能有静态块(编译报错:Illegal static declaration in inner class),但静态内部类可以。
性能与兼容性影响很小,但要注意:匿名内部类、Lambda 表达式没有静态块概念;局部内部类(定义在方法里)也不能有静态块。
实操建议:
- 确认类是否被正确加载——加个
System.out.println("static block")最直接 - 调试时注意 IDE 可能跳过未引用的类,导致静态块不触发(比如只写了
new Outer.Inner(),但Outer没被其他地方引用,JVM 可能延迟加载) - Android 开发中,ProGuard/R8 可能移除“无用”的静态块(如果它只打日志且没副作用),需保留规则
-keepclassmembers class * { static <init>(); }</init>
类加载时机、继承链深度、是否被反射触发,都会影响静态块实际执行时刻;构造块看着简单,但在多线程环境下若涉及共享资源,一样得加同步——这点常被忽略。






