191. Java 异常 - 捕获与处理异常

191. Java 异常 - 捕获与处理异常


在 Java 中,我们通过三大组件来编写异常处理逻辑:

✅ try:用于包裹可能抛出异常的代码块 ✅ catch:用于捕获并处理异常 ✅ finally:无论是否发生异常,都会执行的代码块(如释放资源)

从 Java SE 7 开始,Java 又引入了一个更简洁的语法糖:

✅ try-with-resources:特别适合处理如文件、网络流等需要关闭的资源(实现了 Closeable 接口的类)


🎯 示例讲解:ListOfNumbers 类

我们来看一个例子,这个类的目标是:

  • 创建一个包含 0~9 的整数列表
  • 将这些数字写入一个文本文件 OutFile.txt
java 复制代码
import java.io.*;
import java.util.List;
import java.util.ArrayList;

public class ListOfNumbers {

    private List<Integer> list;
    private static final int SIZE = 10;

    public ListOfNumbers () {
        list = new ArrayList<>(SIZE);
        for (int i = 0; i < SIZE; i++) {
            list.add(i);  // 添加 0~9
        }
    }

    public void writeList() {
        // ❗ 这行会抛出 Checked Exception:IOException
        PrintWriter out = new PrintWriter(new FileWriter("OutFile.txt"));

        for (int i = 0; i < SIZE; i++) {
            // ⚠️ 这行可能抛出 Unchecked Exception:IndexOutOfBoundsException
            out.println("Value at: " + i + " = " + list.get(i));
        }
        out.close();
    }
}

🔍 异常解释(两类异常的区别)

在这段代码中,有两种可能出错的地方:

1️⃣ new FileWriter("OutFile.txt")

  • ❗ 受检异常(Checked Exception)
  • 类型:IOException
  • 含义:可能文件不存在、没有写权限、磁盘满了等问题
  • ✅ 必须显式 try-catch 或 throws

2️⃣ list.get(i)

  • ⚠️ 未受检异常(Unchecked Exception)
  • 类型:IndexOutOfBoundsException
  • 含义:索引越界(比如 i = 10 时)
  • ⚠️ 可以不写 try-catch,编译器不强制要求

✅ 改进:添加异常处理

我们来修改 writeList() 方法,加入适当的异常处理逻辑:

java 复制代码
public void writeList() {
    PrintWriter out = null;
    try {
        out = new PrintWriter(new FileWriter("OutFile.txt"));  // 可能抛 IOException
        for (int i = 0; i <= SIZE; i++) {  // ❗ 有意写错,触发越界
            out.println("Value at: " + i + " = " + list.get(i));
        }
    } catch (IOException e) {
        System.err.println("无法写入文件:" + e.getMessage());
    } catch (IndexOutOfBoundsException e) {
        System.err.println("访问数组越界:" + e.getMessage());
    } finally {
        if (out != null) {
            out.close();  // 无论是否发生异常,最终关闭文件
        }
    }
}

✅ 推荐方式:使用 try-with-resources

java 复制代码
public void writeList() {
    try (PrintWriter out = new PrintWriter(new FileWriter("OutFile.txt"))) {
        for (int i = 0; i < SIZE; i++) {
            out.println("Value at: " + i + " = " + list.get(i));
        }
    } catch (IOException e) {
        System.err.println("文件写入失败:" + e.getMessage());
    }
}

✨ try-with-resources 的好处是:不需要手动关闭资源,系统会帮你自动调用 close(),即使发生异常也不会忘关文件。


🎓小结:

异常来源 异常类型 编译器要求处理? 推荐处理方式
new FileWriter(...) IOException ✅ 是 try-catch 或 throws
list.get(i) 超出范围 IndexOutOfBounds ❌ 否 可以加 catch(防护)
  • "写文件就像租房子,可能租不到------那就得处理!"
  • "数组越界就像走楼梯踩空了,未必每次都摔倒,但总有风险!"
  • "try-with-resources 是自动洗碗机,用了就回不去了。"
相关推荐
Autumn_ing4 小时前
Design.md生成UI怎么验收?举例运营后台的颜色、状态和数据核对
前端·ui·ai·设计系统·paico·ai生成ui·design.md
凤山老林5 小时前
Spring Boot 启动冲刺:耗时剖析、懒加载策略与事件驱动初始化优化
spring boot·后端·python
keyipatience5 小时前
JavaScript学习(1)书写位置,变量、数据类型、运算符
开发语言·前端·javascript·css·学习
朱涛的自习室5 小时前
我给 Gemini 4 和 DeepSeek 搞了套「末位淘汰」,AI 干活会更猛吗?(Day 3)
android·前端·后端
java1234_小锋8 小时前
【技术专题】HTML5 网页技术 - HTML5简介 & HTML5 文档结构
前端·html·html5
woniu_maggie8 小时前
SAP MDG主数据治理实战:从架构原理到项目实施全解析
后端
xiaoqiMikko8 小时前
Redis 实战(一):内存满了 —— 拒写、淘汰、被系统杀掉,以及删了 key 内存为什么不降(6.2.4 实测)
redis·后端
鶴哥只手遮天8 小时前
Vue 3 核心源码深度剖析系列(v3.5.44)-第 1 章 项目全景:monorepo 架构与工程化体系
前端·vue.js·开源
流星。。方8 小时前
小团队官网SEO落地:前端语义化与静态生成的工程实践
前端·状态模式