方法重载判定只看方法名和参数列表(类型、个数、顺序),与参数名、返回值、访问修饰符、异常声明等无关;编译期静态绑定,不涉及运行时多态。

方法重载(Overloading)本身不难,但大厂面试常从它切入,层层递进考察你对 Java 语法细节、编译机制和 JVM 行为的理解。关键不是背定义,而是能说清“为什么这样设计”“边界在哪”“容易踩什么坑”。
重载的判定到底看什么?不是参数名,也不是返回值
Java 编译器只根据方法名 + 参数列表(类型、个数、顺序)来判断是否构成重载。参数名无关紧要;返回类型不同但参数完全一样,不算重载,编译直接报错。
- int add(int a, int b) 和 long add(int x, int y) —— ❌ 不是重载,编译失败
- void print(String s) 和 void print(Object o) —— ✅ 是重载,参数类型不同
- void show(int... nums) 和 void show(int[] arr) —— ❌ 编译报错,二者在字节码层面签名一致
自动类型提升和装箱拆箱,怎么影响重载选择?
当传入实参无法精确匹配某个重载版本时,编译器会按固定优先级尝试隐式转换:精确匹配 → 扩展原始类型转换(如 byte→int)→ 装箱 → 可变参数。这个过程有明确规则,不是“哪个更像选哪个”。
- 有方法:f(int),f(long),f(Integer),调用 f(10) → 选 f(int),不走装箱
- 调用 f(null) 且存在 f(String) 和 f(Integer) → 编译失败,歧义
- 有 f(Object) 和 f(String),传入 null → 选 f(String),因为子类更具体
泛型方法和重载共存时,谁赢?
泛型方法的类型擦除发生在编译后,但重载解析发生在编译期。所以泛型方法参与重载时,编译器看到的是擦除后的签名。如果擦除后和其他方法签名冲突,就可能编译不过,或行为出人意料。
立即学习“Java免费学习笔记(深入)”;
- void process(List
list) 和 <T> void process(List<T> list) —— 擦除后都是 process(List),编译报错 - 解决办法:改参数类型(比如一个用 List,一个用 ArrayList),或避免让泛型方法和具体类型方法同名同形参结构
重载 vs 重写,面试最爱混着问——它们根本不在一个维度
重载是编译期多态,发生在同一个类中,靠参数列表区分;重写是运行期多态,发生在父子类之间,要求方法签名(含返回类型协变)和访问权限满足规则。混淆两者,等于没搞懂 Java 多态的分层设计。
- 重载方法可以改变返回类型(只要参数不同);重写方法返回类型必须相同或协变
- private 方法可被重载,但不能被重写;static 方法可重载,但“重写”只是隐藏,无动态绑定
- 构造器只能重载,不能重写——因为它不属于继承体系中的成员方法
不复杂但容易忽略。把重载当成一个“编译器如何做静态分派”的问题来理解,比死记规则管用得多。


















