2.6 方法
方法 = 会做事的积木:把一段代码起个名字打包,以后喊名字就执行。数据从参数进门,结果从 return 出门——写一次,到处喊。
前置知识:2.2 Java中的变量(形参就是普通变量格子)、2.5 循环结构语句(方法里经常装循环)。
其实你早就在喊方法了:System.out.println(...) 就是喊别人写好的 println 方法干活——本节只是学着自己写一个。
1. 为什么需要方法
不用方法,"算两个数的和"要用三次就得复制粘贴三遍;改需求(比如改成求乘积)要改三处,漏一处就出 bug。方法把这段代码打包成积木:定义一次,哪里要算就喊一次——复用是它唯一的追求。
2. 方法的定义:五个部位
public static int add(int a, int b) {
int sum = a + b;
return sum;
}
| 部位 | 例子 | 作用 |
|---|---|---|
| 修饰符 | public static |
先照抄,第五章面向对象再解释它 |
| 返回值类型 | int |
这个方法干完活,交回来的结果是什么类型 |
| 方法名 | add |
喊它用的名字,小驼峰,见名知义 |
| 参数列表 | int a, int b |
干活需要的原料,几个格子、什么类型 |
| 方法体 | { ... return sum; } |
真正干活的代码 |
- 返回值类型 ↔ return 的东西:声明返回
int,就必须return一个 int 值——说好交整数就得交整数 - 参数列表 ↔ 调用时传的实参:定义收两个 int,调用就必须给两个 int——
add(3)或add(3, 5.0)都直接报错
3. 调用:喊积木干活
public class Demo07 {
public static void main(String[] args) {
int result = add(3, 5); // 喊 add,把 3 和 5 送进去,接住回来的 8
System.out.println(result); // 8
System.out.println(add(10, 20)); // 也可以直接喊,不用接
}
public static int add(int a, int b) {
return a + b;
}
}
调用时发生的四件事(对应上面的图):
add(3, 5)—— 喊名字,递原料(实参:3 和 5)- 3 住进 a,5 住进 b(形参:a、b 就是方法自己的格子)——注意是"复制值进去",方法里改 a 不影响外面的 3
- 执行方法体,算出 8
return把 8 送回调用处,装进result——程序回到原地接着走
形参是定义时的"占位格子"(int a, int b)——形式上的参数,得等人来住;实参是调用时"真送来的值"(3, 5)——实际的参数。对号入座:第 1 个实参住第 1 个形参,数量、类型都得配。
4. 三种常见形态
// ① 无参有返回:不要原料,交结果
public static int getTen() {
return 10;
}
// ② 有参无返回(void):给原料,只干活不回报
public static void printLine(int n) {
for (int i = 0; i < n; i++) {
System.out.print("-");
}
System.out.println(); // 打完一行换行,不需要 return 什么
}
// ③ 有参有返回:最常用
public static double circleArea(double r) {
return 3.14159 * r * r;
}
调用区别:
int x = getTen(); // 有返回值 → 可以接住
printLine(20); // void → 只能直接喊,接不了(int x = printLine(20); 报错)
double s = circleArea(2.5);// 接住 19.63...
int result = printLine(20);编译报错——void 不交货,没法接- void 方法里可以写
return;(不带值),作用是"到此为止,提前回去",类似 2.5 里 break 的急刹效果
5. 方法的三个家规
- 方法必须住在类里,不能裸写在类外面——Java 一切代码都在类里(1.3 就见过的规矩)
- 方法之间不能嵌套定义——方法里不能再写一个方法,积木和平积木
- 定义顺序无所谓——main 在前 add 在后照样能调用(编译器不按行数念经),但执行永远从 main 开始:main 是总指挥,你不喊,方法自己不会动
方法体里定义的变量(包括形参),出了方法的 {} 就消失。两个方法里都写 int temp 互不打架——各自的方法各自的格子。
6. 动手:Demo07 积木三连
第 1 步:IDEA02 项目 → src → New → Java Class → Demo07,psvm 生成主方法。
第 2 步:抄入(方法写在 main 的下面,同一层级):
public class Demo07 {
public static void main(String[] args) {
int result = add(3, 5);
System.out.println(result); // 8
printLine(20); // 打印一行 20 个 -
printLine(30); // 再喊一次,30 个 —— 复用的爽点
System.out.println(circleArea(2.5)); // 19.624...
}
public static int add(int a, int b) {
return a + b;
}
public static void printLine(int n) {
for (int i = 0; i < n; i++) {
System.out.print("-");
}
System.out.println();
}
public static double circleArea(double r) {
return 3.14159 * r * r;
}
}
第 3 步:绿三角 ▶ 运行,核对输出。
第 4 步(两个 30 秒实验):
- 把
add(3, 5)改成add(3)——看"参数数量不对"的报错长什么样(IDEA 红线当场就报) - 把
add里的return a + b;暂时删掉——看"缺少返回语句"的报错。说好交 int 就得交,亲眼见一次
7. 常见误区小结
定义了方法但没人调用它,一个字都不会执行——执行从 main 开始,main 是总指挥。
声明 int 却 return 3.5,报错;声明 int 却漏了 return(某些分支没返回),报错。合同说了交什么就得交什么。
void 不交货。要结果就把返回值类型改成对应类型并 return。
传值是复制:int x = 3; change(x); 方法里把 a 改成 100,外面的 x 还是 3。两套格子,各管各的。
必须住在类的 {} 里、和其他方法平级——不能裸放,也不能套娃。
8. 自测题
定义里的 a、b 是形参(占位格子),调用时的 3、5 是实参(真送来的值)。调用时:3 住进 a、5 住进 b → 执行方法体算 a+b → return 把 8 送回调用处,程序回到原地接着走。
printHello(); 直接喊(不接);int x = getAge(); 接住返回值。不能写 int x = printHello();——void 不交货,编译报错。
public static void main(String[] args) {
int x = 3;
change(x);
System.out.println(x);
}
public static void change(int a) {
a = 100;
}
输出 3。传参是复制值:x 的 3 被复制进 a 的格子,方法里改的是 a,外面的 x 毫发无损。两套格子各管各的。
① if (n % 2 == 0) { return true; } else { return false; }(能用);② boolean flag = n % 2 == 0; return flag;(分步);③ return n % 2 == 0;(最地道——表达式本身就是 boolean,直接交出去)。体会一下"比较运算符的返回值就是 boolean"(2.3)能省多少代码。
不冲突——方法体里定义的变量出了方法的 {} 就消失,两个方法各有各的格子(作用域规则)。方法不能嵌套定义,积木和平积木;方法必须住在类的 {} 里、彼此平级。
9. 下一步学什么
- ☐ 2.7 数组 —— 方法的最佳搭档:一排带编号的格子一个名字管全部,遍历/求和/最大值三件套,数组整包传进方法
- ☐ 动手作业:
Demo07跑通 + 两个 30 秒实验(参数不对、缺 return 的报错各见一次)
10. 相关笔记
- 2.5 循环结构语句 ← 方法体里最常装的就是循环
- 2.2 Java中的变量 ← 形参就是普通变量格子,作用域规则通用
- 1.3 第一个Java程序 ← main 的结构现在终于全懂了
- 📇 Java基础 · 索引
- 🏠 返回主页