193. Java 异常 - Java 异常处理之 Catch 块详解

58 阅读2分钟

193. Java 异常 - Java 异常处理之 Catch 块详解


✅ 什么是 catch 块?

我们已经知道 try 块用来“尝试”执行可能出错的代码。那么,如果真的出错了,程序是如何应对的?

这就要靠 catch 块了!

try {
    // 可能出异常的代码
} catch (异常类型 变量名) {
    // 处理该类型异常的代码
}
  • catch 是异常处理器(Exception Handler
  • 它负责“接住”抛出来的异常对象
  • 每个 catch 块只能处理一种异常类型(除非你合并异常,我们稍后讲)

✍️ 示例:writeList() 方法的两个异常处理器

我们来看两个经典的异常处理写法,分别处理:

  • IndexOutOfBoundsException(未受检)
  • IOException(受检)
try {
    // 可能抛出异常的操作
} catch (IndexOutOfBoundsException e) {
    System.err.println("索引越界异常:" + e.getMessage());
} catch (IOException e) {
    System.err.println("IO异常捕获:" + e.getMessage());
}

📌 注意:

  • JVM 从上往下检查 catch,第一个匹配的就被调用
  • 如果你写错了顺序,比如先捕获父类,再捕获子类,编译器直接报错!

🚫 错误示例:父类异常写在前,子类异常写在后

来看这个错误写法:

try {
    // some IO code
} catch (IOException ioe) {
    // 父类异常处理
} catch (FileNotFoundException fnfe) {
    // 子类异常处理(永远执行不到)
}

💥 错误原因:

  • FileNotFoundExceptionIOException 的子类
  • 所以前面的 IOException 已经把后者包括了,后者永远不会被执行
  • 编译器会提示:“FileNotFoundException 已经被上面的 catch 捕获”

✅ 正确顺序应该是:先写子类,再写父类!


🧠 catch 块内部做什么?

虽然很多初学者的 catch 只是打印错误信息,但其实它能做的更多:

用途示例说明
✅ 打印日志System.err.println(...)
🔁 重试机制比如提示用户重新输入
🧼 资源清理如果没有 finally,你也可以在 catch 中关闭文件或数据库连接
🚀 异常链传递把异常封装后继续向上传递(后面讲 chained exception)

  • “catch 就像安全网,专门接你 try 跳伞失败之后的落地。”
  • “每个 catch 都是一个守门员,只接自己看得懂的球。”
  • “别写错顺序——父类先出场,子类就被‘抢戏’了!”

🎓 小结梳理:

项目要点
写法catch (异常类型 变量名)
顺序子类在前,父类在后
匹配机制异常类型兼容或等于 catch 中声明的类型即可匹配
行为打印、恢复、传递、终止程序都可以在 catch 中进行