java方法重写必须同时满足四大规则:签名完全一致、返回类型协变兼容、访问权限不更严格、检查异常不更宽泛;@override是强制性契约,用于编译期校验重写合法性。

Java 中方法重写(Override)不是简单地“名字一样就行”,而是有明确语法和语义约束的多态基础;@Override 注解也不是可有可无的装饰,它是编译器帮你把关的关键开关——加了它,拼错方法名、参数类型用错包装类、返回类型扩大、访问权限缩紧等问题,都会在编译阶段立刻报错,而不是等到运行时出问题才暴露。
必须满足的四大重写规则
只有同时满足以下全部条件,才算合法重写:
-
方法签名完全一致:方法名、参数个数、每个参数的原始类型(注意:int 和 Integer 不兼容)、参数顺序,必须和父类方法一模一样。例如父类是
void show(int x),子类写成void show(Integer x)属于重载,不是重写,加 @Override 会直接编译失败。 -
返回类型协变兼容:基本类型(如 int、void)和 void 必须严格相同;引用类型允许协变——父类返回
Animal,子类可返回Dog extends Animal;但不能反向扩大,比如父类返回String,子类不能返回Object。 -
访问权限不能更严格:父类是
protected,子类可用protected或public;父类是public,子类只能是public;private和默认(包私有)方法不可被重写(子类根本不可见)。 - 检查异常不能更宽泛:子类重写方法抛出的 checked 异常,只能是父类声明异常的子类,或不抛;RuntimeException 及其子类不受限制。
@Override 注解的正确写法和作用
它不是可选项,而是你主动声明“我要重写”的契约。只要意图是重写,就必须加,且加了就接受编译器审查:
- 放在方法定义上方,紧邻访问修饰符之后,例如:
@Override public void run() { } - 仅适用于重写父类实例方法,或实现接口中的抽象方法、default 方法;对
static、private、final方法加 @Override 会编译失败。 - 接口中 default 方法可被重写,此时应加 @Override;接口 static 方法不能被重写,只能通过接口名调用,加 @Override 也会报错。
- IDE(如 IntelliJ)通常自动生成,但不能代替你理解规则——生成了不代表写对了,得靠自己核对签名和权限。
常见“看似重写实则不是”的情况
这些场景下加 @Override 会立刻暴露错误,是检验你是否真正理解重写的试金石:
- 父类方法是
private:子类同名方法只是新定义,与父类无关,加 @Override 报错 “Method does not override method from its superclass”。 - 父类方法是
static:子类同名static方法属于“隐藏(hiding)”,不是重写;加 @Override 编译失败。 - 父类方法是
final:禁止重写,加 @Override 直接编译报错。 - 父类方法不存在(比如拼错名、少一个参数):加 @Override 会让编译器马上指出问题,避免静默调用父类方法导致逻辑错误。
接口方法实现也要用 @Override
从 Java 6 起,@Override 就支持用于实现接口方法,不只是继承重写:
- 类实现接口时,所有抽象方法都必须重写,推荐统一加 @Override,提升可读性并防止漏写。
- 接口的 default 方法可被重写,此时也应加 @Override;多个接口含同名 default 方法时,子类必须重写以解决冲突,同样需要 @Override。
- 接口的 static 方法不能被重写,也不该加 @Override——它只属于接口本身,调用方式是
InterfaceName.method()。
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











