🧩 方法(函数)
方法定义 · 参数与返回值 · 重载 · 递归 · 值传递陷阱
1. 什么是方法?为什么要用方法?
🍳 类比——调料包:方法就像"麻辣烫调料包":
你写一次配方(方法定义),以后每次想做都直接"拆包"(调用方法),不用重新配。
还可以给包定制:加辣(参数)→ 出不同口味(返回值)。
你写一次配方(方法定义),以后每次想做都直接"拆包"(调用方法),不用重新配。
还可以给包定制:加辣(参数)→ 出不同口味(返回值)。
方法的好处:
- 复用:写一次,到处调用(main 里就不用堆几百行)
- 清晰:给代码块起名,程序像"说明书"(先做 A,再做 B)
- 易维护:改逻辑只改一处
方法的完整结构
// 格式:修饰符 返回值类型 方法名(参数列表) { 方法体 }
public static int add(int a, int b) {
int sum = a + b;
return sum; // 把结果"交出去"
}
// 调用(在 main 里):
int result = add(3, 5); // 传参 3 和 5,得到 8
System.out.println(result);
8
🎯 四要素
- 方法名:动词命名(add、printName、getMax)
- 参数:方法需要的"输入";可以没有(空括号)
- 返回值:方法给调用方的"输出";没有输出写 void(无返回)
- return:立即结束方法并返回值;void 方法里 return 可省略
2. 参数传递:值传递和引用传递?
结论(面试必问):Java 只有值传递——传的是"值的拷贝"。
- 基本类型(int/double…):传的是值的副本,方法里改不影响外面
- 引用类型(String/数组/对象):传的是引用的副本——两个引用指向同一个对象,方法里改对象内容会影响外面;但重新指向新对象不影响外面
基本类型:改了没用
public static void change(int x) { x = 100; }
int a = 10;
change(a);
System.out.println(a); // 还是 10!方法里改的是副本
10
引用类型:改内容会影响
public static void fill(int[] arr) { arr[0] = 99; } // 改数组内容
int[] nums = {1, 2};
fill(nums);
System.out.println(nums[0]); // 99!副本指向同一个数组
99
🎯 一句话记忆
- 基本类型改副本;引用类型"改对象内容"生效、"换新对象"不生效
- 面试问"Java 是值传递还是引用传递":答"值传递",然后解释引用类型传的是引用值的拷贝
3. 什么是方法重载(Overload)?
重载:同一个类里,方法名相同、参数列表不同(个数/类型/顺序不同)。调用时编译器根据参数自动选。
重载示例
public static void print(int n) { System.out.println("整数: " + n); }
public static void print(String s) { System.out.println("字符串: " + s); }
public static void print(int n, String s) { System.out.println(n + " " + s); }
print(10); // 自动匹配第 1 个
print("你好"); // 自动匹配第 2 个
print(1, "号"); // 自动匹配第 3 个
🎯 注意
- 重载与返回值无关:只改返回值不算重载(编译报错)
- System.out.println 本身就是重载(能打印所有类型)
- 重载 vs 重写(Override):重载=同类多版本;重写=子类覆盖父类(后面 OOP 讲)
4. 什么是递归?递归的经典例子?
递归:方法调用自己。适合"问题可以拆成更小的同类问题"的场景。
两个必备条件:① 递归出口(终止条件,否则栈溢出);② 每次调用让问题变小。
递归求阶乘
// n! = n × (n-1)!,0! = 1
public static int fact(int n) {
if (n <= 1) return 1; // ① 出口:0! 和 1! 都是 1
return n * fact(n - 1); // ② 拆小:5! = 5 × 4!
}
// fact(5) = 5×fact(4) = 5×4×fact(3) = ... = 120
// 递归的过程像"套娃":一层层深入,到底后一层层返回
递归输出 1~n 的"先深入后返回"现象
public static void down(int n) {
if (n == 0) return;
System.out.println("进入: " + n);
down(n - 1); // 递归调用在中间
System.out.println("返回: " + n);
}
// 输出顺序:进入 3, 进入 2, 进入 1, 返回 1, 返回 2, 返回 3
✍️ 练习题
- 1. 写方法 max(a,b) 返回两数较大值;max3(a,b,c) 调用两次实现
- 2. 写方法 isEven(n) 判断偶数,isPrime(n) 判断素数
- 3. 递归求 1+2+...+n
- 4. 递归求斐波那契第 n 项(1,1,2,3,5,8...)——先自己想出口和递推式
- 5. 陷阱思考:递归没有出口会怎样?(答案:栈溢出 StackOverflowError)