06 方法¶
本章目标¶
- 理解方法:把一段代码打包,起个名字,随时调用
- 掌握方法的定义、参数、返回值
- 掌握方法重载
- 理解值传递
6.1 什么是方法?¶
方法(也叫函数)就是给一段代码起个名字,需要时调用它。好处:代码复用、结构清晰。
public class Main {
public static void main(String[] args) {
greet("小明"); // 调用方法
greet("小红");
greet("小刚");
}
// 定义方法
static void greet(String name) {
System.out.println("你好," + name + "!欢迎来到服务器");
}
}
输出:
你好,小明!欢迎来到服务器
你好,小红!欢迎来到服务器
你好,小刚!欢迎来到服务器
6.2 方法的语法¶
修饰符 返回值类型 方法名(参数列表) {
方法体
return 返回值; // 如果有返回值
}
| 部分 | 说明 | 例子 |
|---|---|---|
| 修饰符 | public / static 等 | 后面章节讲 |
| 返回值类型 | 返回什么类型的数据 | int / double / void |
| 方法名 | 小驼峰命名 | getPlayerName |
| 参数列表 | 调用时传进来的数据 | (String name, int level) |
| return | 返回结果给调用者 | return total; |
无返回值(void)¶
static void printInfo(String name) {
System.out.println("玩家: " + name);
// 没有 return
}
有返回值¶
static int add(int a, int b) {
return a + b; // 把结果还给调用者
}
// 调用
int result = add(3, 4); // result = 7
return 立即结束方法
方法里一旦执行到 return,后面的代码不再执行。可以提前 return 做"守卫":
static double divide(int a, int b) {
if (b == 0) {
return -1; // 提前返回
}
return (double) a / b;
}
6.3 参数与返回值:值传递¶
Java 是值传递:基本类型传的是"值的副本",方法里改参数不影响外面。
static void tryModify(int x) {
x = 999; // 改的是副本
}
int num = 10;
tryModify(num);
System.out.println(num); // 还是 10!
引用类型(数组、对象)传的是"引用的副本",通过引用修改内容会影响到外面:
static void fill(int[] arr) {
arr[0] = 999; // 修改了同一个数组的内容
}
int[] a = {1, 2, 3};
fill(a);
System.out.println(a[0]); // 999,被改了
记住这个区别
基本类型:方法里改不动外面。
引用类型:方法里能改对象内容,但 arr = new int[3] 这种重新赋值也影响不到外面。
6.4 方法重载(Overload)¶
同一个类里,方法名相同、参数列表不同,就是重载。调用时编译器根据参数自动选择:
static int max(int a, int b) {
return a > b ? a : b;
}
static int max(int a, int b, int c) {
return max(max(a, b), c);
}
static double max(double a, double b) {
return a > b ? a : b;
}
// 调用
max(1, 2); // 用第一个
max(1, 2, 3); // 用第二个
max(1.5, 2.5); // 用第三个
重载规则
参数个数或类型不同即可重载;只看返回类型不同不算重载(会报错)。
模组开发里很常见:比如一个方法既能接受 BlockPos 又能接受三个 int 坐标。
6.5 可变参数(...)¶
static int sum(int... nums) { // 可以传任意多个 int
int total = 0;
for (int n : nums) total += n;
return total;
}
sum(); // 0
sum(1); // 1
sum(1, 2, 3, 4); // 10
可变参数本质是数组,只能放在参数列表最后。
6.6 递归¶
方法自己调用自己,叫递归。必须有终止条件,否则死循环爆栈。
static int factorial(int n) {
if (n <= 1) return 1; // 终止条件
return n * factorial(n - 1); // 调用自己
}
factorial(5); // 120
模组里什么时候用递归
目录树遍历、连锁挖矿的邻接方块搜索、结构递归生成等。不过递归深了会栈溢出,数据量大时优先用循环或队列。
6.7 实战:模组场景¶
// 计算物品栏里某物品的总数
static int countItem(int[] stackSizes, int targetId) {
int count = 0;
for (int size : stackSizes) {
if (size == targetId) count++;
}
return count;
}
// 把玩家经验等级换算成经验值(简化版)
static int levelToExp(int level) {
if (level < 16) return level * level + 6 * level;
return (int) (4.5 * level * level - 162.5 * level + 2220);
}
6.8 小练习¶
- 写方法
isEven(int n)判断偶数,返回 boolean - 写方法
max3(int a, int b, int c)返回最大值 - 重载
printArea:能算正方形(一个参数)和长方形(两个参数)的面积 - 用递归求斐波那契数列第 n 项(注意终止条件)
本章小结¶
- 方法 = 返回值类型 + 方法名 + 参数 + 方法体
- void 无返回值,return 返回值
- 值传递:基本类型改不动外面,引用类型能改内容
- 重载 = 同名不同参
- 递归要有终止条件
下一章:07 面向对象:类与封装