Java方法重写需满足:签名完全一致(含方法名、参数列表)、访问权限不更严格、返回类型协变兼容、检查型异常不扩大;static、final、private方法不可重写。

Java中方法重写(Override)是面向对象多态性的核心机制,但若不遵守规则,轻则编译失败,重则引发运行时逻辑错误。关键在于:子类方法必须与父类被重写方法具有相同的签名(方法名、参数列表),且访问权限不能更严格,返回类型需协变兼容,异常声明不能抛出新或更宽泛的检查型异常。
方法签名必须完全一致
重写要求子类方法名、参数个数、参数类型顺序、参数类型(含泛型擦除后)与父类方法严格一致。注意:
- 仅返回类型不同不算重写,而是编译错误(除非是协变返回类型,见下条)
- 参数名称可以不同,但类型和顺序不可变;int a 和 int b 视为相同参数
- 可变参数(...args)与数组参数(int[] args)在擦除后等价,二者互为重写关系,但混用易引发歧义,应避免
返回类型支持协变,但有明确限制
从Java 5起允许子类重写方法时使用更具体的返回类型(协变返回),前提是该类型是父类方法返回类型的子类型:
- 父类方法返回 Object,子类可返回 String 或自定义类(如 User)
- 但不能返回无关类型(如 Integer 重写返回 String 的方法)
- 基本类型和其包装类之间不构成协变关系(int 与 Integer 不能互相重写)
访问修饰符不能更严格,异常声明不能扩大
子类重写方法的可见性只能等于或大于父类方法(private 方法不可被重写):
立即学习“Java免费学习笔记(深入)”;
- 父类是 protected,子类可用 public,但不能用 private 或包级(默认)
- 关于异常:子类方法可抛出更少或更具体的检查型异常(IOException → FileNotFoundException),但不能新增或抛出更宽泛的检查型异常(如父类没声明异常,子类不能加 throws Exception)
- 运行时异常(RuntimeException 及其子类)不受此限,可自由添加或删除
常见误判与陷阱
这些情况看似像重写,实为重载或编译错误:
- static 方法不能被重写(可被隐藏),子类同名静态方法与父类静态方法构成“隐藏”,调用取决于引用类型而非实际类型
- final 方法不能被重写,编译直接报错
- 父类方法为 private,子类中同名方法只是新定义,与重写无关(因为 private 方法不可见、不可继承)
- 忘记加 @Override 注解:虽非强制,但强烈建议添加——它让编译器帮你校验是否真正在重写,避免拼写错误(如 hashcode() 写成 hashCode())导致意外重载







