方法重载仅由方法名、参数个数和参数类型(顺序)决定,与返回类型、修饰符、异常声明无关;重载解析在编译期按“最精确匹配”原则进行,构造器重载规则相同,需区分重载与重写。

方法重载只看参数列表,和返回类型无关
Java 判断是否构成重载,**完全依据方法名 + 参数个数 + 参数类型(顺序)**,返回类型、修饰符(public/static等)、异常声明统统不影响重载判定。哪怕两个方法仅返回类型不同,编译器会直接报错:method xxx() is already defined。
常见错误现象:写完两个只有 int 和 long 返回值不同的同名方法,以为是重载,结果编译失败。
- 参数类型必须是可区分的原始类型或引用类型,比如
void foo(int)和void foo(Integer)可以共存(自动装箱不改变重载判断时机) - 可变参数
foo(String...)本质是数组,所以和foo(String[])不能同时存在,否则编译报错 - 泛型擦除后若签名一致(如
bar(List和) bar(List),也不算重载)
重载解析发生在编译期,按“最精确匹配”原则选方法
调用时没有运行时多态,JVM 在编译阶段就锁定具体调用哪个重载版本。它从所有候选方法中挑一个“最具体”的:参数类型越接近实参类型,优先级越高。
例如有 print(Object)、print(String)、print(CharSequence),传入 "abc" 会选 print(String);但传入 null 时,如果只有 print(String) 和 print(Integer),编译器会报错 —— 因为 null 对两者都“同样模糊”。
立即学习“Java免费学习笔记(深入)”;
- 基本类型会优先匹配同类型,其次才考虑宽化(
byte→int),不触发自动装箱/拆箱来选重载 -
varargs是最后兜底选项,只有没找到更精确匹配时才启用 - 子类对象传给父类参数的方法,优先于
Object版本,比如Dog实例会优先匹配feed(Animal)而非feed(Object)
构造器也能重载,且常用于对象初始化控制
构造器重载规则和普通方法完全一致,只是没有返回类型。实际开发中,常通过多个构造器暴露不同初始化粒度:
public class User {
private String name;
private int age;
public User(String name) {
this(name, 0); // 委托给另一个构造器
}
public User(String name, int age) {
this.name = name;
this.age = age;
}
}
注意:构造器链式调用(this(...))必须是第一行语句;若没显式写,编译器会默认插入 super(),此时不能再写 this(...)。
- 避免在多个构造器里重复写相同初始化逻辑,优先用
this(...)委托 - 不要让重载构造器之间产生歧义,比如
User(String, int)和User(int, String)容易被误用 - IDE 自动生成的构造器(如全参、无参)可能和手写重载冲突,保存前留意编译错误
重载与重写的区别必须分清,否则设计会出问题
重载(overload)是同一个类里多个同名方法共存;重写(override)是子类改写父类已有方法。二者目的完全不同:重载解决“同一操作的不同输入形式”,重写解决“同一行为的不同实现”。混淆会导致预期外的静态绑定或动态绑定行为。
典型陷阱:父类定义了 draw(Shape),子类想扩展为 draw(Circle) 和 draw(Rectangle),但如果没在父类也声明对应版本,那子类这些方法只是重载,不是重写 —— 多态调用时不会被触发。
- 重写要求方法签名(含参数)完全一致,重载则必须不同
- @Override 注解只能用于重写,加在重载方法上会编译报错
- private / static / final 方法无法被重写,但可以被重载(只要参数不同)
null 的歧义性、构造器委托顺序、以及和重写的边界,都是容易在重构或协同开发中突然暴露的问题。








