方法重载
方法重载(Overload)让同一个方法名在不同参数下做不同的事。名字相同,参数不同,编译器会根据调用时传入的参数自动选择正确版本。
为什么需要重载
试想没有重载的世界:
java
// ❌ 必须给每个方法起不同的名字
int addInt(int a, int b) { return a + b; }
double addDouble(double a, double b) { return a + b; }
String addString(String a, String b) { return a + b; }有了重载,简洁多了:
java
// ✅ 同一个名字,参数列表不同
int add(int a, int b) { return a + b; }
double add(double a, double b) { return a + b; }
String add(String a, String b) { return a + b; }重载让 API 更简洁。调用者不需要记一堆方法名,记住一个就够了。
重载的判断规则
重载只关心一件事:参数列表必须不同。
java
public class OverloadRules {
// 这四个方法都构成重载
void process(int a) { } // 参数个数不同
void process(int a, int b) { } // 参数个数不同
void process(double a) { } // 参数类型不同
void process(int a, double b) { } // 参数顺序不同
void process(double a, int b) { } // 参数顺序不同
}下面这些不会构成重载:
java
public class NotOverload {
// ❌ 只有返回值不同,不算重载
int method() { return 0; }
// String method() { return ""; } // 编译错误
// ❌ 只有参数名不同,不算重载
void process(int a) { }
// void process(int b) { } // 编译错误
// ❌ 只有 static 修饰符不同,不算重载
static void process(int a) { }
// void process(int a) { } // 编译错误
}与重写的对比
| 对比项 | 重写 (Override) | 重载 (Overload) |
|---|---|---|
| 发生位置 | 父子类之间 | 同一个类中 |
| 方法名 | 必须相同 | 必须相同 |
| 参数列表 | 必须相同 | 必须不同 |
| 返回类型 | 必须相同或其子类 | 可以相同或不同 |
| 访问修饰符 | 不能缩小 | 无关 |
| 关系 | 同一个方法的不同实现 | 完全不同的方法 |
java
class Parent {
void display(int x) {
System.out.println("Parent: " + x);
}
}
class Child extends Parent {
// 这是重写:参数列表相同
@Override
void display(int x) {
System.out.println("Child: " + x);
}
// 这是重载:参数列表不同
void display(String s) {
System.out.println("Child: " + s);
}
}
public class OverloadVsOverride {
public static void main(String[] args) {
Child obj = new Child();
obj.display(10); // 重写版本
obj.display("hello"); // 重载版本
}
}构造方法重载
重载最常见的应用场景就是构造方法:
java
public class User {
private String name;
private int age;
private String email;
// 无参构造
public User() {
this.name = "匿名";
}
// 单参构造
public User(String name) {
this.name = name;
}
// 双参构造
public User(String name, int age) {
this.name = name;
this.age = age;
}
// 全参构造
public User(String name, int age, String email) {
this.name = name;
this.age = age;
this.email = email;
}
}调用时,编译器根据参数自动选择:
java
new User(); // 无参构造
new User("张三"); // 单参构造
new User("李四", 25); // 双参构造
new User("王五", 30, "a@b.com"); // 全参构造细节:类型自动转换
当没有精确匹配的方法时,编译器会尝试自动类型转换:
java
public class TypePromotion {
void process(int a) {
System.out.println("int: " + a);
}
void process(double a) {
System.out.println("double: " + a);
}
public static void main(String[] args) {
TypePromotion obj = new TypePromotion();
obj.process(10); // 精确匹配 int 版本
obj.process(10.5); // 精确匹配 double 版本
obj.process('A'); // char → int,自动提升
obj.process((short) 5); // short → int,自动提升
}
}匹配优先级:精确匹配 > 自动类型提升 > 自动装箱 > varargs
java
public class PriorityDemo {
void process(int i) {
System.out.println("int");
}
void process(Integer i) {
System.out.println("Integer");
}
void process(Object o) {
System.out.println("Object");
}
void process(int... arr) {
System.out.println("varargs");
}
public static void main(String[] args) {
PriorityDemo obj = new PriorityDemo();
Integer num = 10;
obj.process(10); // int(精确匹配)
obj.process(num); // Integer(精确匹配)
obj.process("hello"); // Object
obj.process(1, 2, 3); // varargs
}
}常见错误
1. 与重写混淆
java
class Parent {
void display(int a) {
System.out.println("Parent");
}
}
class Child extends Parent {
void display(int a, int b) { // 这不是重写,是重载!
System.out.println("Child");
}
}2. 误以为返回类型影响重载
java
class Example {
int getValue() { return 1; }
// double getValue() { return 1.0; } // ❌ 编译错误:只有返回类型不同
}实际应用
Java 标准库中到处是重载的影子:
java
// String 类
"hello".indexOf(99); // 从指定位置开始查找
"hello".indexOf('e'); // 查找字符
"hello".indexOf("ell"); // 查找子串
"hello".indexOf("e", 1); // 从指定位置开始查找子串
// System.out
System.out.println(); // 换行
System.out.println(true); // 打印布尔
System.out.println(100); // 打印整数
System.out.println("hello"); // 打印字符串
System.out.println('A'); // 打印字符总结
方法重载让同一个名字承载多种功能,关键规则只有一条:参数列表必须不同。
记住这张选择图:
调用 method(x)
↓
有没有 method(精确类型)? → 有 → 调用
↓ 无
有没有 method(自动提升类型)? → 有 → 调用 (int → long → double → Object)
↓ 无
有没有 method(自动装箱类型)? → 有 → 调用 (int → Integer)
↓ 无
有没有 method(可变参数)? → 有 → 调用
↓ 无
编译错误