JAVA学习之异常

JAVA异常

Java 异常(Exception)是 Java 语言中用于处理程序运行时错误和非正常流程的核心机制。它允许程序在遇到问题时优雅地处理,而不是直接崩溃

1.异常体系结构

Java 的所有异常都继承自 java.lang.Throwable 类,主要分为两大分支

scss 复制代码
Throwable
├── Error (严重错误)
│   ├── OutOfMemoryError      (内存溢出)
│   ├── StackOverflowError    (栈溢出)
│   └── NoClassDefFoundError  (类定义缺失)
│
└── Exception (可处理的异常)
    ├── Checked Exception (受检异常/编译时异常)
    │   ├── IOException
    │   ├── SQLException
    │   └── ClassNotFoundException
    │
    └── RuntimeException (非受检异常/运行时异常)
        ├── NullPointerException      (空指针)
        ├── ArrayIndexOutOfBoundsException (数组越界)
        ├── ClassCastException        (类型转换错误)
        ├── IllegalArgumentException  (非法参数)
        └── ArithmeticException       (算术异常,如除零)

2.三大核心分类

分类 说明 编译器检查 典型示例 处理建议
Error JVM 层面的严重问题,程序无法恢复 ❌ 不检查 OOM、StackOverflow 不应捕获,应修复代码或调整JVM参数
Checked Exception 外部因素导致的可预见异常 ✅ 必须处理 IO、网络、数据库 用 try-catch 或 throws 声明
RuntimeException 编程逻辑错误导致的异常 ❌ 不检查 空指针、越界 通过代码规范避免,而非依赖捕获

3.异常处理关键字

  1. try: 包裹可能抛出异常的代码块
  2. catch: 捕获并处理特定类型的异常(可多个,子类在前父类在后)
  3. finally: 无论是否异常都会执行,常用于资源释放
  4. throw: 手动抛出一个异常对象
  5. throws: 在方法签名上声明该方法可能抛出的异常
java 复制代码
// 标准用法示例
public String readFile(String path) throws IOException {
    BufferedReader reader = null;
    try {
        reader = new BufferedReader(new FileReader(path));
        return reader.readLine();
    } catch (FileNotFoundException e) {
        System.err.println("文件不存在: " + path);
        throw e; // 重新抛出
    } catch (IOException e) {
        System.err.println("读取失败: " + e.getMessage());
        return null;
    } finally {
        // 传统方式关闭资源
        if (reader != null) {
            try { reader.close(); } catch (IOException ignored) {}
        }
    }
}

4.现代最佳实践

使用 try-with-resources(Java 7+)自动管理资源

java 复制代码
try (BufferedReader reader = new BufferedReader(new FileReader(path))) {
    return reader.readLine();
} // 自动关闭,无需 finally
  1. 精确捕获:只捕获你能处理的异常,不要笼统地 catch (Exception e)
  2. 保留异常链:重新包装异常时传入原始异常 new ServiceException("msg", cause)
  3. 使用日志框架记录异常:log.error("描述", e) 而非 e.printStackTrace()
  4. 自定义业务异常:继承 RuntimeException,携带错误码和业务信息

避免

  1. 吞掉异常:catch 块为空或仅打印消息而不处理/传播
  2. 用异常控制业务流程:异常有性能开销,不应用于正常逻辑分支
  3. 在 finally 中 return:会覆盖 try/catch 中的返回值和异常
  4. 过度使用 Checked Exception:现代框架(Spring等)普遍倾向 RuntimeException

5.自定义异常示例

java 复制代码
public class BusinessException extends RuntimeException {
    private final int code;

    public BusinessException(int code, String message) {
        super(message);
        this.code = code;
    }

    public BusinessException(int code, String message, Throwable cause) {
        super(message, cause); // 保留异常链
        this.code = code;
    }

    public int getCode() { return code; }
}

// 使用
if (user == null) {
    throw new BusinessException(404, "用户不存在");
}

6.面试高频点速记

  1. NoClassDefFoundError vs ClassNotFoundException:前者是运行时找不到类(Error),后者是动态加载时找不到(Checked Exception)
  2. final / finally / finalize 的区别
  3. try-with-resources 的原理:AutoCloseable 接口 + 编译器生成关闭代码
  4. 异常对性能的影响:创建异常对象时需要填充栈快照(fillInStackTrace),这是主要开销
相关推荐
文丑颜不良啊24 分钟前
LeetCode2261~2280题目解析
java·leetcode
SL_staff38 分钟前
告别规则黑盒:JVS-Rules 在金融风控中的可视化决策编排实践
java·产品·全栈
逃逸线LOF1 小时前
服务网关Gateway
java·运维·gateway
灿飞屋2 小时前
Kotlin与Java虚拟机四:函数
java·python·kotlin·安卓·android jetpack
阡陌数智3 小时前
Claude API新版本重大变更与安全升级指南
java·linux·安全
学长毕设4 小时前
基于SpringBoot的野生动物公益保护平台设计与实现-附源码
java·spring boot·后端
SL_staff5 小时前
离散制造排程破局:JVS-APS 四步闭环落地实践(开发者视角)
java·产品·全栈
这个昵称不容易5 小时前
SpringBoot 美容院管理系统:232个Java文件315个接口,5套角色从预约到发货一整条链路
java·springboot·毕设
装不满的克莱因瓶6 小时前
【SpringAI Alibaba】ReactAgent记忆管理MessageTrimmingHook与MessageDeletionHook
java·人工智能·ai·ai编程·springai·springaialibaba
文丑颜不良啊6 小时前
LeetCode2241~2260题目解析
java·leetcode