重载发生在同一类中,靠参数列表不同实现编译期静态绑定;重写发生在父子类间,靠方法签名相同实现运行期动态绑定,支持协变返回、访问权限扩大和异常范围收窄。

重载和重写是 Java 面试绕不开的“双子星”,高频、易混、爱挖坑。想真正拿下,不能只背定义,得从发生位置、判定依据、编译运行机制、常见误判点四个维度系统梳理。
重载(Overload):编译期靠参数“认人”
只发生在同一个类中(或父子类中同名方法共存时,但本质仍是类内多义),核心是“同名不同参”。编译器在编译阶段就根据调用处传入的实参类型、个数、顺序,静态匹配到唯一方法。
- ✅ 合法重载的三种方式:参数个数不同(
add(int)vsadd(int, int))、参数类型不同(add(int)vsadd(String))、参数顺序不同(add(int, String)vsadd(String, int)) - ❌ 四大无关项:返回值类型、访问修饰符(public/private)、异常声明、static/final 修饰——仅改这些,编译直接报错,不构成重载
- ⚠️ 注意隐式转换陷阱:比如
add(int)和add(long)同时存在,调用add(5)会选int版;但若只有add(long),则5会被自动提升为long调用它——面试常考“为什么没报错?”
重写(Override):运行期靠对象“定调”
必须发生在父子类之间,是动态多态的根基。JVM 在运行时根据对象实际类型(而非引用类型),查虚方法表(vtable)决定执行哪个版本。
Java项目代码review工具。分析Git变更+完整调用链路上下文,推断业务需求,进行多维度评分和分类汇总,生成完整PRD文档。包含细粒度Java代码审查清单(Null安全、异常处理、Streams、并发、equals/hashCode、资源管理、API设计、性能、MyBatis/ORM、事务边界、SQL/DD...
- ✅ 方法签名必须一致:方法名 + 参数列表(个数、类型、顺序)完全相同
- ✅ 返回值允许协变:父类返回
Animal,子类可返回Dog(JDK 1.5+);基本类型和 void 必须严格一致 - ✅ 访问权限只能扩大:父类
protected,子类可public,但不能private或包权限 - ✅ 异常范围只能缩小或不变:子类方法不能抛出父类未声明的检查异常,可抛出其子类或不抛
- ❌ 三类方法无法重写:
private(不可见)、static(属于类,非对象)、final(禁止覆盖)
关键对比:一眼分清谁是谁
别再记“重载是同名不同参,重写是同名同参”这种模糊口诀。记住这三点本质差异:
立即学习“Java免费学习笔记(深入)”;
- 发生位置不同:重载在同一个类里“横向扩展功能”;重写在父子类间“纵向升级行为”
- 绑定时机不同:重载是静态绑定(编译期确定),重写是动态绑定(运行期确定)
- 调用依据不同:重载看引用变量声明时的实参;重写看 new 出来的对象真实类型
高频避坑点:面试官最爱追问的7个雷区
这些不是冷知识,是筛选“真懂”和“背过”的分水岭:
- 子类定义了与父类
private方法同名的方法?→ 不是重写,只是新方法(父类 private 对子类不可见) - 父类
static方法,子类也写一个同签名的static方法?→ 是“隐藏”(hiding),不是重写;调用取决于引用类型,不是对象类型 - 构造方法能被重写吗?→ 不能。构造方法名必须与类名一致,父子类名不同,根本不可能同名,更谈不上重写
- 重写时把
throws IOException改成throws Exception?→ 编译失败。检查异常范围只能收窄 - 接口默认方法能否被实现类重写?→ 可以,规则与普通重写一致(JDK 8+)
- 重载方法能否分布在父类和子类中?→ 可以(如父类有
test(String),子类加test(int)),但调用受引用类型限制:用父类引用只能看到父类定义的方法 - @Override 注解加不加有影响吗?→ 加了是编译期校验(写错会报错);不加不报错,但失去保护,容易误以为是重写而实际是重载或新方法

















