最根本的防护是只在构造器中调用final或private方法;将初始化方法显式声明为final或private;推迟多态逻辑至对象创建后,通过init()等方法统一初始化;采用工厂方法封装构建与初始化流程;并添加运行时校验和编译期拦截机制。

只在构造器中调用 final 或 private 方法
这是最根本、最可靠的防护手段。final 和 private 方法无法被子类重写,父类构造器调用时永远执行本类版本,字段访问完全可控。
- 把所有被构造器调用的初始化方法显式加上 final 修饰符,例如:
final void loadConfig() { ... } - 若方法仅用于内部初始化,直接改为 private——语义更清晰,且天然不可重写
- 避免使用
protected或public非 final 方法,哪怕当前没被重写,也埋下隐患
把多态逻辑推迟到对象创建完成之后
构造器只该做三件事:分配内存、设置 final 字段、校验参数。所有依赖子类字段或需定制行为的操作,必须移出构造流程。
Java Maven 项目审查工作流的通用输入处理。当 Java Maven 项目以 ZIP压缩包或 GitLab 仓库 URL 形式提供且需要...时使用。
- 提供一个公共的 init()、configure() 或 start() 方法,由使用者在
new后主动触发 - 该方法可设计为
protected abstract,让子类自由实现,此时字段已就绪、时机可控 - 对连接池、配置加载等关键资源,采用惰性加载:用
Supplier或双重检查封装,首次访问才执行
用工厂方法统一控制构建和初始化
把“创建 + 初始化”收口到静态工厂中,既规避构造阶段不确定性,又便于注入统一保障能力。
- 定义
public static T create(...),内部先new T(...),再立即调用init() - 工厂内可加入异常包装、监控埋点、超时控制,提升生产环境鲁棒性
- 配合私有构造器,强制使用者走工厂路径,防止绕过初始化逻辑
加运行时防护和编译期拦截
靠约定不可靠,要让问题在写代码时或构建时就被发现。
- 在父类中设私有标志位
private boolean initialized = false,init()成功后置为true - 关键业务方法开头加判断:
if (!initialized) throw new IllegalStateException("Call init() first") - IDE(如 IntelliJ)开启检查项 “Call to non-final method from constructor”,实时标红
- CI 阶段集成 ErrorProne,扫描构造器中对非 final 方法的调用,发现即阻断
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南










