Java子类如何合理复用父类已执行的耗时计算逻辑?
避免子类构造时重复执行父类耗时计算的方案
针对你给出的代码场景,要实现“先创建父类,再基于父类创建子类且不重复执行父类耗时计算”,可以通过以下几种合理设计实现:
方案一:通过带参构造复用已有父类的计算结果
核心思路是给父类新增一个接收预计算值的构造方法,子类通过传入已创建的父类实例的value,跳过父类构造中的耗时计算。
修改后的父类代码
public class Parent { protected int value; // 原无参构造,用于直接创建父类实例(仅执行一次耗时计算) public Parent() { value = performHeavyCalculations(); } // 新增受保护的带参构造,直接传入已计算好的value protected Parent(int precomputedValue) { this.value = precomputedValue; } private int performHeavyCalculations() { // 你的耗时计算逻辑 return 100; } }
修改后的子类代码
public class Child extends Parent { private int newValue; // 新增构造方法,接收已有的Parent实例 public Child(Parent existingParent) { // 调用父类带参构造,直接复用已有父类的value,避免重复计算 super(existingParent.value); newValue = value + performAnotherHeavyCalculations(); } private int performAnotherHeavyCalculations() { // 你的另一耗时计算逻辑 return 50; } }
使用方式
// 先创建父类,仅执行一次耗时计算 Parent parent = new Parent(); // 基于已有父类创建子类,复用父类的计算结果 Child child = new Child(parent);
方案二:静态缓存父类计算结果(适用于所有实例共享结果的场景)
如果父类的耗时计算结果是全局唯一的,所有父类、子类实例都可以共享这个结果,那么可以用静态缓存来确保计算只执行一次。
修改后的父类代码
public class Parent { protected int value; // 静态变量缓存计算结果,保证全局只计算一次 private static Integer cachedValue; public Parent() { // 双重检查锁实现线程安全的懒加载缓存 if (cachedValue == null) { synchronized (Parent.class) { if (cachedValue == null) { cachedValue = performHeavyCalculations(); } } } this.value = cachedValue; } private int performHeavyCalculations() { // 你的耗时计算逻辑 return 100; } }
子类代码无需额外修改
原来的子类构造方法可以直接使用,无论创建多少个Parent或Child实例,performHeavyCalculations()只会执行一次。
方案三:将耗时计算从构造器中移出,手动控制初始化时机
把父类的耗时计算逻辑从构造器中剥离,改为手动触发初始化,这样可以灵活控制计算时机,子类直接复用已初始化的父类状态。
修改后的父类代码
public class Parent { protected int value; private boolean initialized = false; // 构造器仅做基础初始化,不执行耗时计算 public Parent() {} // 手动触发耗时计算的方法 public void initialize() { if (!initialized) { value = performHeavyCalculations(); initialized = true; } } // 静态工厂方法,方便创建已初始化的父类实例 public static Parent createInitialized() { Parent parent = new Parent(); parent.initialize(); return parent; } private int performHeavyCalculations() { // 你的耗时计算逻辑 return 100; } }
修改后的子类代码
public class Child extends Parent { private int newValue; public Child(Parent initializedParent) { // 直接复用已初始化父类的状态 this.value = initializedParent.value; this.initialized = initializedParent.initialized; newValue = value + performAnotherHeavyCalculations(); } private int performAnotherHeavyCalculations() { // 你的另一耗时计算逻辑 return 50; } }
使用方式
// 创建并初始化父类实例 Parent parent = Parent.createInitialized(); // 基于已初始化的父类创建子类 Child child = new Child(parent);
内容的提问来源于stack exchange,提问作者i1ravenov
相关产品推荐
相关产品推荐

