正在加载...

Java 中的 try 和 catch

把错误的 slots[5] 读取包进 try 和 catch,让程序不要在 ArrayIndexOutOfBoundsException 上结束。在 catch 里打印 blocked,再在两个块之外打印 after。编译 Guard.java 并运行 java Guard。屏幕应先显示 blocked,再显示 after。第二个文件把 slots[0] 留在 try 里,这样会跳过 catch,屏幕显示 2,再显示 after。把 throw 留给下一页。

接住坏索引

异常页已经说明:在 {2, 4} 上打印 slots[5] 会抛出 ArrayIndexOutOfBoundsException 并停止运行。本页保留同一段数组故事,并加上处理。打开名为 Guard.java 的新教学文件。保留公共类名 Guard,好与文件名一致。删掉仍会无 catch 就停住的残留 Alarm 的 main、Crate 的 Integer 列表,以及任何 Scanner 或 nextLine。程序不得等待输入。
在 main 里保留同一个小数组:
int[] slots = {2, 4};
把错误打印放进 try:
System.out.println(slots[5]);
再写一个点名 ArrayIndexOutOfBoundsException 并打印 blocked 的 catch。在整个 try 和 catch 之后打印 after。catch 参数名可以是短字母如 e;本页不必打印异常对象。

Guard catch bad index

java
public class Guard {
    public static void main(String[] args) {
        int[] slots = {2, 4};
        try {
            System.out.println(slots[5]);
        } catch (ArrayIndexOutOfBoundsException e) {
            System.out.println("blocked");
        }
        System.out.println("after");
    }
}

在放有 Guard.java 的文件夹里运行 javac Guard.java。当圆括号、花括号和分号都匹配时,javac 自己不写任何一行。再运行 java Guard——不要 java Guard.java。运行命令里去掉 .java 后缀。
屏幕显示 blocked,然后是 after。坏索引仍在 try 里抛出。catch 处理该具名异常并打印 blocked。System.out.println("after"); 在外面,因此仍会执行。程序不会像裸的坏 Alarm 文件那样在这次停止上结束。
设想同一 try 里在 slots[5] 之后还有第二次打印,例如会打印 rice 的一行。那一行不会运行。接住异常不会回头把 try 的剩余部分跑完。只有 catch 体为这次停止运行,然后控制在 catch 之后继续。把想法说清楚:处理会跳过抛出点之后仍留在 try 里的行。
若终端在等键盘输入,说明某个文件里还留着旧练习的 nextLine 调用。删掉它。若只看到堆栈报告而没有 blocked 行,说明缺 catch,或异常名不匹配。若只看到 2 而没有 after,你可能还在运行旧的安全 Alarm 文件——改用带 catch 教学文件的 java Guard。

当 try 完成时,catch 保持安静

第二个程序使用同样的 try 和 catch 形状,但 try 里的打印请求已写入的槽位:slots[0]。try 里的每一行都完成。catch 体不运行。

Guard safe index skips catch

java
public class Guard {
    public static void main(String[] args) {
        int[] slots = {2, 4};
        try {
            System.out.println(slots[0]);
        } catch (ArrayIndexOutOfBoundsException e) {
            System.out.println("blocked");
        }
        System.out.println("after");
    }
}

用 javac Guard.java 编译,再运行 java Guard。屏幕显示 2,然后是 after。不会打印 blocked,因为没有 ArrayIndexOutOfBoundsException。catch 保持安静。after 行仍会运行,因为它在两个块之外——与 catch 演示里同一位置。
把对照走一遍。第一个文件:坏索引,catch 打印 blocked,然后 after。第二个文件:安全索引,跳过 catch,屏幕是 2 然后 after。两者都保留 Guard 和同一个 catch 类型名。只有 try 里的索引改变。这一处改动就足以看出 catch 何时运行、何时不运行。
本页不要编造 throw。你接住的是坏数组读取本就会引起的异常。下一页讲故意抛出。今天也不要把课程里每一次安静打印都包进 try——本课在已知坏索引需要被处理路径时使用 try。

catch 名必须匹配

catch 子句点名一种异常类型。本页该类型是 ArrayIndexOutOfBoundsException,与坏索引匹配。若在 slots[5] 外写成 catch (NullPointerException e),该 catch 不会处理这次停止。程序仍会以 ArrayIndexOutOfBoundsException 结束,且对该不匹配的 catch 既不打印 blocked 也不打印 after。在教学文件里保留匹配的类型。
Java 里还有别的异常名。本页只保留一对清楚的例子:坏数组索引与 ArrayIndexOutOfBoundsException。练习这种形状之前,不需要每种可捕获类型的目录。与异常页见过的名字对齐。

与裸 Alarm 停止对照

在异常页,带 slots[5] 的 java Alarm 停住并显示堆栈报告。在本页,同一坏索引下的 java Guard 打印 blocked 并继续到 after。数组故事没变。处理变了。若附近还有 Alarm 文件,只当作历史留下;对 catch 演示运行 java Guard,让屏幕符合本课。
若保留旧文件,wrappers 历史仍会从 Integer 列表打印 9。那条路径不是 catch 故事。删除或忽略 Guard.java 里残留的 ArrayList<Integer> 演示,让教学文件留在 int[] slots 加上 try 和 catch。

本页留给 throwing 的内容

本页接住一行本就会撞上的异常。下一页引入 throw,让你自己发信号报告问题。此处先留在匹配的 catch 以及看到 after 继续。先不要在这些 Guard 文件上把手动 throw 当成硬性要求。

在 throwing 之前

你可以从 slots[5] 接住 ArrayIndexOutOfBoundsException,看到 blocked,再看到 after。你可以把 slots[0] 留在 try 里,看到 2,再看到 after,并跳过 catch。编译 Guard.java,对每个保留的演示轮流运行 java Guard。catch 名与坏索引停止匹配。下一页是 throwing,你会故意造成停止。
保留 catch 演示以得到处理路径。保留安全 try 以安静跳过 catch。把手动 throw 留在本页之外。这三条习惯是继续前进前的检查点。当 java Guard 的坏索引运行后先出现 blocked 再出现 after,try 和 catch 就完成本课任务,你已准备好学习关于抛出的下一主题。

🧠 测试您的知识

准备开始

测试您的知识

通过这个互动测验挑战自己,看看你对这个主题的理解程度如何

❓
5
问题
🎯
70%
及格要求
♾️
∞
时间
🔄
∞
尝试次数

📝 说明

  • 仔细阅读每个问题
  • 为每个问题选择最佳答案
  • 您可以随时重新参加测验
  • 您的进度将显示在顶部