钩子方法是在抽象类中定义的带默认实现的protected方法,用于在模板方法的关键位置提供可选扩展点,命名常为beforeXxx、afterXxx等,需保持安全、无副作用且文档清晰。

在抽象类里设计钩子方法,核心是预留“可插拔”的干预点,不强制子类实现,但允许它在关键位置悄悄介入流程。它不是主干逻辑,而是为灵活性留的后门。
钩子方法的基本写法
钩子方法本质是带默认实现(常为空)的 protected 方法,定义在抽象类中,子类按需覆盖:
- 用
protected修饰,避免外部调用,只供子类继承使用 - 方法体可以为空(
{}),也可以有安全、无副作用的默认行为(比如返回true、打印日志、做轻量初始化) - 命名要直白,常见前缀包括:
beforeXxx、afterXxx、shouldXxx、isXxxEnabled
嵌入模板方法的合适位置
钩子方法必须被模板方法(final)主动调用,且放在有意义的节点上,比如:
-
前置干预:在核心操作前执行,如
beforeProcess()可用于参数预处理或权限检查 -
条件开关:用布尔钩子控制分支,如
shouldRetry()决定是否重试 -
后置清理:在主逻辑完成后执行,如
afterSave()用于发通知或清缓存 -
扩展埋点:如
onSuccess()或onFailure(),方便子类加监控或日志
典型结构示例
一个清晰的抽象类骨架:
立即学习“Java免费学习笔记(深入)”;
abstract class OrderProcessor {
public final void execute() {
validate(); // 具体方法
beforeSubmit(); // 钩子:子类可选覆盖
submitOrder(); // 抽象方法(必须实现)
if (shouldNotify()) { // 钩子:控制分支
sendNotification();
}
afterSubmit(); // 钩子:子类可选清理
}
<pre class='brush:java;toolbar:false;'>protected void beforeSubmit() {} // 空钩子
protected void afterSubmit() {} // 空钩子
protected boolean shouldNotify() {
return true; // 默认发通知,子类可改
}
protected abstract void submitOrder();
private void validate() { /* 公共校验 */ }
private void sendNotification() { /* 默认邮件 */ }}
设计时要注意的细节
钩子方法看似简单,但容易踩坑:
- 默认实现不能抛异常、不能修改共享状态、不能依赖其他钩子——保持独立和安全
- 不要在钩子里做耗时或核心业务,它只是“插手点”,不是主流程载体
- JavaDoc 要写清楚用途,例如:
/** 子类可重写此钩子,在订单提交前做风控校验 */ - 避免多个钩子相互耦合,比如
beforeXxx()不该依赖afterYyy()的结果


















