构造块在工厂模式中与直接new对象时行为完全一致:只要工厂方法内部执行new,构造块就在对象实例化过程中、构造函数体执行前按源码顺序执行一次;它由JVM在new时自动触发,与工厂实现方式无关,仅响应new操作,不执行于缓存、clone或非new创建场景。

构造块在工厂模式中,和普通 new 对象时完全一致:只要工厂方法内部执行了 new,构造块就会在对应对象实例化过程中、构造函数体执行之前,按源码顺序执行一次。
工厂方法调用 new 时,构造块照常触发
工厂模式本身不改变 Java 对象创建机制。无论通过简单静态工厂、抽象工厂还是 Builder,只要底层用了 new Xxx(),JVM 就会走标准初始化流程:
- 分配内存 → 初始化字段默认值(0 / null / false)→ 执行构造代码块(按书写顺序)→ 执行构造函数体
- 构造块不是“被工厂调用”的,而是被 JVM 在 new 过程中自动插入的,与谁写 new 无关
- 哪怕工厂返回的是缓存对象(如单例或对象池),只要没走 new,构造块就不会执行——它只响应 new 操作
常见工厂场景下的实际表现
不同工厂实现对构造块的影响差异明显:
-
简单工厂(每次都 new):每次调用
createProduct()都触发构造块,和直接 new 效果一样 - 单例工厂(首次 new 后复用):构造块仅在第一次获取实例时执行一次,后续 get 返回已有对象,不触发
- 原型模式工厂(clone 而非 new):不执行构造块——clone 绕过构造函数和构造块,直接复制内存状态
- 依赖注入容器(如 Spring):默认使用反射 + new 创建 bean,构造块仍执行;若配置为 prototype 且启用构造注入,同样触发;但若用 setter 注入或 @Autowired 字段注入,不影响构造块执行时机
构造块在工厂类里容易被误用的位置
注意两个典型误区:
立即学习“Java免费学习笔记(深入)”;
- 把构造块写在工厂类里(而非产品类里):那只是工厂对象自身的初始化逻辑,和它生产的对象无关
- 在工厂方法内部写局部 {} 块:这是普通代码块,属于方法执行流,和对象构造完全无关
- 以为“工厂封装了 new,所以能控制构造块是否执行”:不能。只要 new 发生,构造块就不可跳过(除非用 Unsafe.allocateInstance 等非常规手段)
验证建议:用最简工厂+日志确认
写一个带构造块的产品类和静态工厂,打印日志就能直观看到时机:
class Product {{ System.out.println("构造块执行"); }
public Product() { System.out.println("构造函数执行"); }
}
class ProductFactory {
public static Product create() {
System.out.println("进入工厂方法");
return new Product(); // 此处触发构造块
}
}
调用 ProductFactory.create(),输出顺序必为:
进入工厂方法 → 构造块执行 → 构造函数执行


















