Java枚举常量内实例化ExpensiveObject的性能影响及单例相关疑问
单例服务中
ExpensiveObject的初始化开销详解 先给你明确核心结论:
- 创建
ExpensiveObject的开销绝对是一次性的 - 开销默认在首次引用
MyServiceImpl时产生,不过也有可配置的例外情况
为什么开销是一次性的?
因为MyServiceImpl是隐式单例——整个应用生命周期里只会被实例化一次。假设你的代码是常见的单例服务结构:
@Service // 以Spring为例,@Service默认是单例 public class MyServiceImpl { // 初始化开销大的对象 private final ExpensiveObject expensiveObj = new ExpensiveObject(); public void doBusiness() { expensiveObj.runTask(); } }
成员变量expensiveObj的初始化逻辑只会在MyServiceImpl唯一的实例被创建时执行一次,后续无论多少次调用doBusiness(),都不会再重新创建ExpensiveObject,所以初始化开销只会发生一次。
开销的触发时机
这取决于单例的初始化策略:
- 默认懒加载(多数框架的默认行为)
比如Spring的单例Bean默认是懒加载模式——直到第一次被其他组件注入、或者你主动调用它的方法时,MyServiceImpl才会被实例化,这时才会触发ExpensiveObject的创建,开销就在这个首次引用的时刻产生。 - 饿汉式加载(手动配置)
如果你给MyServiceImpl加上@Lazy(false)(Spring)或者其他框架的类似配置,这个单例会在应用启动阶段(上下文初始化时)就被实例化,ExpensiveObject的初始化开销会提前到应用启动时,而非首次引用。
避坑提醒
如果你的ExpensiveObject是在MyServiceImpl的方法内部每次调用都创建(如下错误示例),那开销就会重复产生,但这显然不是你提问的场景,还是提一下避免踩坑:
// 错误示例:每次调用都新建对象,开销重复出现 public void badBusinessMethod() { ExpensiveObject tempObj = new ExpensiveObject(); tempObj.runTask(); }
内容的提问来源于stack exchange,提问作者senseiwu
相关产品推荐
相关产品推荐

