← Java 基础教程

第 13 / 40 课 · 免费教程

附魔台的参数与返回值

参数 return 与重载

100–120 分钟本章使用 JDK 21,无需预览功能。基础进阶

本课作品

制作练习伤害计算器

会用参数把数据送进方法;会用 return 把结果带回调用处;能编写 boolean 查询方法并理解重载;最终完成考虑武器、锋利、暴击和护甲的伤害计算器。 前置背包:会定义并调用 static 方法。上一课的配方卡只有固定材料;这一课给它装上材料槽和成品出口。

开始前:建议先完成第 12 课

方法的材料槽与成品出口
  1. 实参提供本次材料
  2. 方法按契约计算
  3. 返回值调用者接收结果

01 / 15

开始前:把示例放对地方

本章使用 JDK 21,不需要预览功能。每个普通示例都给出完整程序,按标注的文件名保存。多个示例各放在自己的文件夹,避免辅助类同名。

终端命令:把中文占位符替换成实际名称

javac -encoding UTF-8 示例文件名.java
java 示例类名

类名区分大小写。完整挑战代码若分成多段,请按顺序接在同一个文件中,不要为续段另建类。运行核对只列程序输出;需要输入的地方另给输入序列。

02 / 15

附魔台不收心灵感应

附魔师问:“基础伤害多少?锋利几级?这次暴击吗?”玩家回答:“你猜。”附魔师把书一合:方法不会心灵感应。

参数是方法定义里的材料槽,实参是调用时真正放进去的数据。返回值则是方法完成计算后交出来的成品。

方法需要明确的材料槽
  1. base基础伤害,double
  2. sharp锋利等级,int
  3. critical暴击状态,boolean
  4. armor目标护甲,double

带着四个问题出发

  • 形参和实参分别出现在哪里?
  • 多个参数为什么必须按顺序传入?
  • void 与有返回值的方法有什么区别?
  • 重载为什么不能只改返回类型?

03 / 15

参数槽和实参材料

double base 和 int level 是形参;7.0 和 3 是实参。调用发生时,实参值会进入对应参数。

数据经过方法的路线
  1. 实参调用处提供值
  2. 形参与计算方法使用值的副本
  3. return把结果交回调用处

L13Example02.java · 完整独立示例

public class L13Example02 {
    static double damage(double base, int level) { return base + level * 1.5; }
    public static void main(String[] args) {
        System.out.println(damage(7.0, 3));
        System.out.println(damage(5.0, 0));
        System.out.println(damage(8.0, 2));
    }
}

运行结果

11.5
5.0
11.0

04 / 15

多个参数不能站错格

如果两个参数类型相同,传反后 Java 可能照样编译。房子会从 9×7 变成 7×9,然后理直气壮地说自己没有报错。

参数顺序就是工作台格子顺序
  1. width第一项,横向宽度
  2. height第二项,纵向高度
  3. 正确调用9,7得到宽9高7
  4. 传反7,9能编译但含义改变

L13Example03.java · 完整独立示例

public class L13Example03 {
    static void describeArea(int width, int height) {
        System.out.println(width + " x " + height);
    }
    public static void main(String[] args) {
        int houseWidth = 9, houseHeight = 7;
        describeArea(houseWidth, houseHeight);
        describeArea(houseHeight, houseWidth);
    }
}

运行结果

9 x 7
7 x 9

调用检查

  • 参数太多时,每个实参单独一行。
  • 使用含义清楚的变量名,不直接堆数字。
  • 测试宽高不同的值,传反时更容易看出来。

05 / 15

return 把结果送回来

有返回值的方法像工作台:放入材料,取出成品。return 一执行,方法立刻结束,并把值交给调用处。 本例每种材料限定0到64;非法输入返回0是本方法约定,不是所有计算方法都应采用的策略。

数据经过方法的路线
  1. 实参调用处提供值
  2. 形参与计算方法使用值的副本
  3. return把结果交回调用处

L13Example04.java · 完整独立示例

public class L13Example04 {
    static int torchCount(int coal, int sticks) {
        if (coal < 0 || sticks < 0 || coal > 64 || sticks > 64) return 0;
        return Math.min(coal, sticks) * 4;
    }
    public static void main(String[] args) {
        int torches = torchCount(7, 10);
        System.out.println(torches);
        System.out.println(torchCount(2, 5) >= 8);
    }
}

运行结果

28
true

06 / 15

提前 return 守住边界

边界检查放在方法开头,能让后面的正常公式保持清楚。提前返回不是逃课,而是保安把负数苦力怕请出工作台。

坏输入先在门口被拦住
  1. 负数量直接返回0
  2. 正常数量按配方计算
  3. 过大材料本例超过64也拒绝
  4. 锋利等级修正到0到5

L13Example05.java · 完整独立示例

public class L13Example05 {
    static int torchCount(int coal, int sticks) {
        if (coal < 0 || sticks < 0 || coal > 64 || sticks > 64) return 0;
        return Math.min(coal, sticks) * 4;
    }
    static int safeLevel(int level) { return Math.max(0, Math.min(5, level)); }
    public static void main(String[] args) {
        System.out.println(torchCount(-1, 3));
        System.out.println(torchCount(0, 64));
        System.out.println(safeLevel(9));
    }
}

运行结果

0
0
5

07 / 15

boolean 方法回答真假

返回 boolean 的方法适合回答问题。调用处读起来像一句话,因此方法名要带问题味道。

查询方法像红石检测器
  1. canCraftPickaxe仅检查材料数量
  2. true材料至少3钻石2木棍
  3. false有一种材料不足
  4. 调用处根据答案决定后续动作

L13Example06.java · 完整独立示例

public class L13Example06 {
    static boolean canCraftPickaxe(int diamonds, int sticks) {
        return diamonds >= 3 && sticks >= 2;
    }
    public static void main(String[] args) {
        System.out.println(canCraftPickaxe(5, 1));
        if (canCraftPickaxe(3, 2)) System.out.println("材料够了");
    }
}

运行结果

false
材料够了

08 / 15

同名方法的不同配方

重载让相关操作共享一个方法名,但参数列表必须不同。它适合“同一动作,不同材料组合”。

重载共享名字 参数列表不同
  1. 单参数版本物品名,默认数量1
  2. 双参数版本物品名与数量
  3. 重载规则参数列表必须不同
  4. 调用Java按参数选择版本

L13Example07.java · 完整独立示例

public class L13Example07 {
    static void giveItem(String item) { giveItem(item, 1); }
    static void giveItem(String item, int count) {
        System.out.println(item + " x" + count);
    }
    public static void main(String[] args) {
        giveItem("钻石");
        giveItem("火把", 16);
    }
}

运行结果

钻石 x1
火把 x16

09 / 15

Java 怎样选择重载

调用重载方法时,Java 查看实参的数量和类型。若两个版本都同样合适,就会出现“我该进哪扇门”的编译错误。

实参类型决定走哪条轨道
  1. show(int)整数3选择这个版本
  2. show(double)3.5选择这个版本
  3. 类型转换整型可兼容变为double
  4. 注意不能只靠返回类型选择

L13Example08.java · 完整独立示例

public class L13Example08 {
    static void show(int n) { System.out.println("整数 " + n); }
    static void show(double n) { System.out.println("小数 " + n); }
    public static void main(String[] args) {
        show(3);
        show(3.5);
    }
}

运行结果

整数 3
小数 3.5

10 / 15

伤害公式拆开计算

复杂公式不要塞进一行。先计算武器与锋利,再处理暴击,最后扣除护甲,并用 Math.max 防止伤害变成负数。

数据经过方法的路线
  1. 实参调用处提供值
  2. 形参与计算方法使用值的副本
  3. return把结果交回调用处

L13Example09.java · 完整独立示例

public class L13Example09 {
    static double damage(double base, int sharp,
            boolean critical, double armor) {
        if (!Double.isFinite(base) || !Double.isFinite(armor)) return 0;
        base = Math.max(0, Math.min(100, base));
        sharp = Math.max(0, Math.min(5, sharp));
        armor = Math.max(0, Math.min(100, armor));
        double raw = base + sharp * 1.5;
        if (critical) raw *= 1.5;
        return Math.max(0, raw - armor);
    }
    public static void main(String[] args) {
        System.out.println(damage(7, 2, false, 5));
        System.out.println(damage(7, 5, true, 0));
    }
}

运行结果

5.0
21.75

11 / 15

三类测试照出漏洞

测试不是“多点几次运行”。每个测试要有输入、预期和实际结果。

正常 边界 错误测试缺一不可
  1. 正常普通命中与暴击
  2. 边界等级0或5,护甲0
  3. 错误负数与非有限小数
  4. 比较小数测试允许极小误差

L13Example10.java · 完整独立示例

public class L13Example10 {
    static double damage(double base, int sharp,
            boolean critical, double armor) {
        if (!Double.isFinite(base) || !Double.isFinite(armor)) return 0;
        base = Math.max(0, Math.min(100, base));
        sharp = Math.max(0, Math.min(5, sharp));
        armor = Math.max(0, Math.min(100, armor));
        double raw = base + sharp * 1.5;
        if (critical) raw *= 1.5;
        return Math.max(0, raw - armor);
    }
    public static void main(String[] args) {
        double result = damage(7, 2, false, 5);
        System.out.println(Math.abs(result - 5.0) < 0.0001);
        System.out.println(damage(-2, 9, false, -1));
        System.out.println(damage(Double.NaN, 2, false, 0));
    }
}

运行结果

true
7.5
0.0
验收表
类别输入 base, sharp, critical, armor预期
正常7, 2, false, 55.0
边界0, 0, false, 00.0
边界7, 5, true, 021.75
修正-2, 9, false, -17.5
错误NaN, 2, false, 00.0

12 / 15

参数与返回值故障诊所

先读方法头,它就是契约。调用处必须提供正确数量和类型的实参;非 void 方法的每条可达路径都要返回值。

四种故障都能从方法契约定位
  1. 漏返回有路径没有return
  2. 重载冲突参数一样,仅改返回类型
  3. 少实参数量不匹配
  4. 修复核对方法契约

BadReturn.java · 故意错误示例

public class BadReturn {
    static int count(int n) { if (n > 0) return n; }
    public static void main(String[] args) { }
}

BadOverload.java · 故意错误示例

public class BadOverload {
    static int value(int n) { return n; }
    static double value(int n) { return n; }
    public static void main(String[] args) { }
}

13 / 15

挑战 伤害计算器

新建 DamageCalculator.java。挑战 方法对负数输入做保护,把锋利限制在0到5,再计算最终伤害。

四个输入汇入一个可测试的方法
  1. 输入契约base和armor在0到100
  2. 等级契约sharp修正到0到5
  3. 计算规则自定义练习伤害
  4. 输出契约返回有限且非负的值

DamageCalculator.java · 完整独立示例

public class DamageCalculator {
    static double damage(double base, int sharp,
            boolean critical, double armor) {
        if (!Double.isFinite(base) || !Double.isFinite(armor)) return 0;
        base = Math.max(0, Math.min(100, base));
        sharp = Math.max(0, Math.min(5, sharp));
        armor = Math.max(0, Math.min(100, armor));
        double raw = base + sharp * 1.5;
        if (critical) raw *= 1.5;
        return Math.max(0, raw - armor);
    }
    public static void main(String[] args) {
        System.out.println(damage(7, 2, false, 5));
        System.out.println(damage(7, 5, true, 0));
        System.out.println(damage(-2, 9, false, -1));
    }
}

运行结果

5.0
21.75
7.5

14 / 15

拓展任务与通关复盘

每档都要写至少三个测试,其中必须有一个边界值。

三档任务让配方卡真正会变
  1. 木镐材料计算与边界
  2. 铁镐坐标距离方法
  3. 钻石镐增加有区别的重载
  4. 复盘解释形参与实参

三档作业

  • 木镐:写 torchCount(coal, sticks),返回最多能合成的火把数量。
  • 铁镐:写 distance(x1, y1, x2, y2),返回两点直线距离。
  • 钻石镐:重载三种 giveItem,分别支持默认数量、指定数量和指定玩家。
验收表
自评能还要练
我能解释形参与实参□□
我能使用 return□□
我能判断重载是否成立□□

15 / 15

自己的验收记录

运行之前写预期,运行之后记录实际结果。正常案例说明程序会做事;边界案例说明它知道何时停;错误案例说明它能拒绝不合理的请求。

把证据写进记录
类别你选择的输入预期与实际
正常一个常用值或一次成功操作是否逐行一致?
边界最小值、最大值及相邻值有没有少一格、多一步?
错误非法数量、缺失对象或错误语法是否明确拒绝?状态是否保持?
  • 把一个 Bug 写成:触发条件、现象、原因、最小修复。
  • 整理一个值得记住的规则,用自己的话解释,不能只复制定义。
  • 改变一个示例,保留测试记录,让结果证明你的理解。

TAKE IT WITH YOU

下载本课 PDF

完整课文、代码、图解与练习,选择你需要的语言。