Skip to content

异常体系与资源管理总览 ​

学习目标 ​

  • 区分 Error、checked exception 和 RuntimeException 的责任边界。
  • 知道 throw、throws、try-with-resources 与 suppressed exception 分别解决什么问题。
  • 能跳转到异常处理和自定义异常页面,按场景复制代码。

核心知识点 ​

专业术语 ​

  • Throwable:Error 与 Exception 的共同根类型。
  • checked exception:编译器要求捕获或声明的 Exception 分支。
  • unchecked exception:RuntimeException 及 Error 分支,不要求在签名中声明。
  • try-with-resources:自动调用 AutoCloseable.close() 的资源管理语句。
  • suppressed exception:主异常发生后,资源关闭等辅助失败被附加保存的异常。

白话解释与边界 ​

Error 通常表示虚拟机或运行环境级严重问题,不应被业务 catch 统一吞掉;RuntimeException 常表示输入、状态或编程错误;checked exception 适合调用方有明确恢复路线的外部失败。异常处理的重点不是“捕获越多越好”,而是让知道如何恢复的层负责恢复。

详细案例已拆分:

常用用法 ​

按异常责任选择捕获或传播 ​

当前层能给出安全默认值时才恢复;没有恢复策略时应保留上下文继续传播。

java
// 语义:当前层能给出安全默认值时才恢复。
public class ExceptionBoundaryOverviewDemo {
    static int parse(String value) {
        try {
            return Integer.parseInt(value);
        } catch (NumberFormatException error) {
            return 0;
        }
    }

    public static void main(String[] args) {
        System.out.println(parse("bad"));
        // 输出:0
    }
}

用 try-with-resources 关闭资源 ​

资源按声明逆序关闭;完整的多资源、finally 和关闭异常案例见异常处理常用写法。

java
// 语义:资源按声明逆序关闭。
import java.io.StringReader;
import java.io.BufferedReader;
import java.io.IOException;

public class ResourceOverviewDemo {
    public static void main(String[] args) throws IOException {
        try (BufferedReader reader =
                 new BufferedReader(new StringReader("java"))) {
// 初始状态:new StringReader("java") 提供一行文本,BufferedReader reader 包装该字符流并在 try 结束时自动关闭。
            System.out.println(reader.readLine());
            // 输出:java
        }
    }
}

用 cause 保留底层异常 ​

异常转换时补充当前层语境,但不要丢掉 cause;领域异常的构造器和结构化字段见自定义异常页面。

java
// 语义:异常转换时补充当前层语境,但不要丢掉 cause。
// 初始状态:root 初始为 new IllegalStateException("db down");translated 初始为 new RuntimeException("load failed", root)。
public class CauseOverviewDemo {
    public static void main(String[] args) {
        IllegalStateException root = new IllegalStateException("db down");
// 关键变化:root 接收表达式 new IllegalStateException("db down") 的计算结果。
// 初始状态:root 的初始值为 new IllegalStateException("db down")。
        RuntimeException translated = new RuntimeException("load failed", root);
// 初始状态:translated.message 为 "load failed",cause 指向 message="db down" 的 root。
        System.out.println(translated.getCause().getMessage());
        // 输出:db down
    }
}

不常用但需要知道 ​

读取 suppressed exception ​

suppressed 用于保留主异常之外的关闭或审计失败;日志排查资源问题时不能只看主异常消息。

java
public class SuppressedOverviewDemo {
    public static void main(String[] args) {
        IllegalStateException main = new IllegalStateException("body");
// 关键变化:main 接收表达式 new IllegalStateException("body") 的计算结果。
// 初始状态:main 的初始值为 new IllegalStateException("body")。
        main.addSuppressed(new IllegalStateException("close"));
// 关键变化:main.addSuppressed(...) 把 message="close" 的异常加入 suppressed 数组第 0 项。
        System.out.println(main.getSuppressed()[0].getMessage());
        // 输出:close
    }
}

识别 finally return 的覆盖风险 ​

finally 中 return 会覆盖原返回值和异常,新代码只在 finally 做清理,不改变控制流。

java
public class FinallyOverviewDemo {
    static int value() {
        try {
            return 1;
        } finally {
            return 2;
        }
    }

    public static void main(String[] args) {
        System.out.println(value());
        // 输出:2
    }
}

简单案例 ​

java
public class ExceptionOverviewDemo {
    static int parse(String value) {
        try {
            return Integer.parseInt(value);
        } catch (NumberFormatException error) {
            return 0;
        }
    }

    public static void main(String[] args) {
        System.out.println(parse("bad"));
        // 输出:0
    }
}

简单输入错误在当前层可以恢复;资源关闭、异常链和自定义异常分别见两个细粒度页面。

易混点 ​

  • throw 是抛出对象,throws 是方法声明;后者不会自动处理异常。
  • catch Exception 不是通用恢复方案,Error 通常不应被业务代码捕获。
  • try-with-resources 的关闭异常通常进入 suppressed,不会简单覆盖主体异常。
  • finally 中 return 会掩盖原异常,资源清理应使用无返回值的 finally 或 try-with-resources。

课后小问 ​

  1. 为什么资源关闭异常需要放到 suppressed? 答案:主体异常已经说明主要故障,关闭异常作为辅助诊断信息附加保存。 解析:同时保留两类异常可以避免资源释放失败被吞掉,也避免它覆盖调用方更关心的主体异常。

  2. 异常体系总览页和细粒度页面如何配合? 答案:先用本页判断责任边界,再按需要打开异常处理常用写法或自定义异常页面复制案例。 解析:总览页负责术语和选择,细节页把每个 API 作为独立小标题,适合直接检索。

本节小结 ​

  • Throwable 层次帮助划分恢复、传播和严重故障边界。
  • try-with-resources 管理资源生命周期,suppressed 保存辅助关闭故障。
  • 异常翻译必须保留 cause,finally 不应改变控制流。
  • 具体代码按场景拆到两个关联页面,原 URL 继续作为入口保留。

快速回顾 ​

  • 能区分 checked、unchecked 和 Error。
  • 能解释 throw、throws、finally 的职责。
  • 能说出资源关闭顺序和 suppressed 的来源。
  • 能从本页跳转到对应的异常速查页面。