方法重写必须加@Override注解,严格遵守契约(如equals/hashCode成对重写、异常范围不扩大、访问权限不缩小),限制重写范围(final/private/static不可重写),以保障多态安全与设计可维护性。

方法重写不是“能用就行”的语法技巧,而是团队面向对象设计落地的关键支点。规范它,本质是在统一多态行为的表达方式、约束继承契约的可维护性,并防止因随意重写引发的隐性bug。
必须加 @Override 注解
这是最基础也最容易被忽视的硬性要求。不加注解时,编译器无法验证你是否真的重写了父类方法——拼错方法名、参数类型写成 int 而非 Integer、少一个参数,都会悄悄变成新方法(重载),而非重写。运行时调用的仍是父类逻辑,问题往往延迟暴露在测试或线上。
- 所有覆写父类(含接口默认方法)的方法,无一例外要加 @Override
- 抽象类中重写抽象方法也要加,它同样参与多态分派
- IDE 通常支持自动补全该注解,应设为保存时自动插入
严格遵守方法契约,尤其对 equals / hashCode / toString
重写 Object 类核心方法不是“改个输出”,而是在定义对象身份语义。例如重写 equals() 必须满足自反性、对称性、传递性、一致性,且与 hashCode() 保持一致:若两个对象 equals 返回 true,则它们的 hashCode 必须相等。
- 业务实体类只要参与集合操作(如放进 HashSet、作 HashMap 的 key),就必须同时重写 equals 和 hashCode
- 禁止只重写 equals 而忽略 hashCode,否则 HashMap 中可能查不到已存入的对象
- toString 建议返回关键字段,便于日志排查,但不必强制——除非团队约定所有 DTO/VO 都需可读字符串表示
限制重写范围,明确哪些方法不该被覆盖
不是所有父类方法都适合重写。团队需在基类设计阶段就通过修饰符传达意图:
Java项目代码review工具。分析Git变更+完整调用链路上下文,推断业务需求,进行多维度评分和分类汇总,生成完整PRD文档。包含细粒度Java代码审查清单(Null安全、异常处理、Streams、并发、equals/hashCode、资源管理、API设计、性能、MyBatis/ORM、事务边界、SQL/DD...
立即学习“Java免费学习笔记(深入)”;
- final 方法禁止重写,适用于核心逻辑稳定、安全敏感或性能关键的方法(如 String.length())
- private 方法不可见,子类中同名方法只是新定义,不是重写;应避免这种“伪重写”造成理解混淆
- static 方法属于类,子类中同名方法是隐藏(hiding),不具多态性;团队规范应明令禁止用 static 方法模拟重写行为
- 构造方法不能重写,也不应试图“绕过”——子类应通过 super() 显式调用父类构造逻辑
重写时保持异常与访问权限的兼容性
重写不是推倒重来,而是在父类划定的契约内提供更具体的实现。这直接影响上层代码的健壮性:
- 子类重写方法不能抛出比父类更宽泛的受检异常(checked exception)。若父类声明 throws IOException,子类可不抛、或只抛 FileNotFoundException,但不能抛 Exception
- 访问权限只能扩大,不能缩小:父类 protected,子类可用 public 或 protected,但不能降为 package-private 或 private
- 返回类型支持协变(JDK 5+):父类返回 Animal,子类可返回 Dog(Dog 是 Animal 子类),这是安全且鼓励的,能提升类型精度
这些规则不是为了增加开发负担,而是把多态从“运行时才看得到的行为”变成“编译期就能校验的契约”。团队在 Code Review 中重点检查 @Override 是否缺失、equals/hashCode 是否成对出现、final/static/private 使用是否合理,就能大幅减少继承滥用带来的设计腐化。

















