背景与动机
方法用于把一段可复用逻辑封装起来,让程序从“堆在 main 里的一串语句”变成“按职责组织的小块逻辑”。
学方法时,重点不是只会写语法,而是理解:
- 方法如何接收参数。
- 方法如何返回结果。
- 方法重载如何区分。
- 重载和重写到底有什么区别。
- Java 参数传递到底传的是什么。
核心原理拆解
1. 方法定义
基本格式:
返回值类型 方法名(参数列表) { 方法体}例如:
static int add(int a, int b) { return a + b;}这里 add 接收两个 int 参数,返回一个 int 结果。
可变参数
可变参数用
类型...定义,可变参数相当于数组类型:
class Group { private String[] names;
public void setNames(String... names) { this.names = names; }}Group g = new Group();g.setNames("Xiao Ming", "Xiao Hong", "Xiao Jun"); // 传入3个Stringg.setNames("Xiao Ming", "Xiao Hong"); // 传入2个Stringg.setNames("Xiao Ming"); // 传入1个Stringg.setNames(); // 传入0个String2. 没有返回值使用 void
static void printHello() { System.out.println("hello");}void 表示方法不返回结果。
3. return 结束方法并返回值
static int max(int a, int b) { if (a > b) { return a; } return b;}对于有返回值的方法,所有执行路径都必须能返回对应类型的结果。
4. 方法重载
同一个类中,方法名相同但参数列表不同,叫方法重载:
static int add(int a, int b) { return a + b;}
static double add(double a, double b) { return a + b;}重载只看方法名和参数列表,不靠返回值区分。
5. 重载和重写不是一回事
很多初学者会把“重载”和“重写”混在一起,但它们解决的是两个不同的问题。
- 重载:同一个类里,方法名相同,参数列表不同。
- 重写:子类继承父类后,用相同的方法签名重新实现父类行为。
一个看参数列表,一个看继承关系。
class Animal { void speak() { System.out.println("animal"); }}
class Dog extends Animal { @Override void speak() { System.out.println("wang"); }}
public class MethodCompare { static int add(int a, int b) { return a + b; }
static int add(int a, int b, int c) { return a + b + c; }}上面 add 和 add 是重载,因为参数个数不同;Dog.speak() 和 Animal.speak() 是重写,因为子类覆盖了父类同签名方法。
可以先记一个最实用的判断法:
- 同一个类里同名不同参,通常是在说重载。
- 父子类之间同名同参,通常是在说重写。
6. Java 参数传递是值传递
Java 方法参数传递的是变量值的副本。
基本类型传的是具体值的副本;引用类型传的是引用值的副本。引用类型参数可以通过这个引用修改对象内部状态,但不能让调用方变量改指向另一个对象。
这里最容易卡住的点是:Java 里没有 C 或 C++ 那种“把指针本身当参数语法直接暴露出来”的写法,所以通常不说 Java 有“指针传参”。更准确的说法是:
- Java 只有值传递。
- 如果参数是基本类型,复制的是数值本身。
- 如果参数是引用类型,复制的是引用值。
也就是说,方法拿到的永远只是一个副本,只不过这个副本有时是 10,有时是“指向某个对象的引用值”。
下面这个例子把“修改对象内容”和“修改引用指向”放在一起看,会更清楚:
class User { String name; int age;
User(String name, int age) { this.name = name; this.age = age; }}
public class PassDemo { public static void main(String[] args) { User user = new User("Tom", 20); changeUser(user); System.out.println(user.name + ", " + user.age); }
static void changeUser(User ref) { ref.age = 30; ref = new User("Jerry", 18); }}输出仍然是:
Tom, 30原因分两步看:
ref.age = 30改的是原对象内部状态,所以调用方能看到变化。ref = new User("Jerry", 18)改的是参数副本自己的指向,不会改掉main里user变量本身。

最小可运行代码示例
public class MethodDemo { public static void main(String[] args) { System.out.println(add(1, 2)); System.out.println(add(1.5, 2.5));
int n = 10; changeNumber(n); System.out.println(n); }
static int add(int a, int b) { return a + b; }
static double add(double a, double b) { return a + b; }
static void changeNumber(int value) { value = 99; }}输出中 n 仍然是 10,因为方法里修改的是参数副本。
常见陷阱与错误示例
1. 以为返回值不同就能重载
错误示例:
static int get() { return 1;}
static String get() { return "1";}方法重载不能只靠返回值类型区分。
2. 有返回值的方法遗漏 return
错误示例:
static int max(int a, int b) { if (a > b) { return a; }}当 a <= b 时没有返回值,编译器会报错。
3. 误以为引用参数能改变调用方变量指向
方法能通过引用修改对象内容,但不能通过给参数重新赋值来改变调用方变量本身。
4. 把重写和重载混为一谈
重载发生在同一个类中,核心是参数列表不同;重写发生在继承体系中,核心是子类重新实现父类已有方法。二者名字相近,但判断依据完全不同。
面试高频问题
1. 什么是方法重载
同一个类中方法名相同、参数列表不同的方法构成重载。参数列表包括参数个数、类型和顺序。
2. 方法重载能不能只靠返回值区分
不能。调用方法时编译器主要根据方法名和参数列表选择目标方法,不能只靠返回值判断。
3. 重载和重写的区别是什么
重载是同一个类里同名不同参的方法;重写是子类对父类同签名方法的重新实现。重载主要体现编译期的方法选择,重写主要体现运行期的多态分派。
4. Java 是值传递还是引用传递
Java 是值传递。引用类型参数传递的是引用值的副本,不是变量本身。
5. Java 有没有指针传参
通常不这样说。Java 没有对开发者暴露 C 或 C++ 那种可直接操作的指针参数语法。更准确的表述是:Java 只有值传递,引用类型参数传递的是引用值的副本。
一句话总结
Java 方法用于封装可复用逻辑;重载看同名不同参,重写看父子类同签名覆盖;参数传递本质上始终是值传递,引用类型也只是传递引用值的副本。