Java中的异常

Java 异常详解

异常(Exception)是程序运行时发生的不正常情况(错误或意外),Java 通过异常处理机制让程序在出错时不会直接崩溃,而是能优雅地处理错误。

一、异常的核心概念

1. 异常的分类

Java 中所有异常都继承自 Throwable 类,主要分为两大分支:

  • Error(错误) :JVM 层面的严重问题(如内存溢出、虚拟机崩溃),程序无法处理,只能避免(如 StackOverflowErrorOutOfMemoryError)。
  • Exception(异常) :程序本身可以处理的问题,又分为:
    • 受检异常(Checked Exception) :编译时必须处理(捕获或声明抛出),如 IOExceptionSQLException
    • 非受检异常(Unchecked Exception) :运行时才会出现,编译时无需强制处理,如 NullPointerExceptionArrayIndexOutOfBoundsException(继承自 RuntimeException)。
2. 常见异常示例

表格

异常类型 说明
NullPointerException 调用空对象的方法 / 属性
ArrayIndexOutOfBounds 数组下标越界
ClassCastException 类型转换失败
ArithmeticException 算术错误(如除以 0)
IOException IO 操作失败(如文件读写)

二、异常的处理方式

Java 处理异常的核心是 try-catch-finallythrows/throw

1. 捕获异常(try-catch-finally)

语法

java

运行

复制代码
try {
    // 可能抛出异常的代码
} catch (异常类型1 变量名) {
    // 处理异常类型1
} catch (异常类型2 变量名) {
    // 处理异常类型2(注意:子类异常要写在父类前面)
} finally {
    // 无论是否发生异常,都会执行(常用于释放资源,如关闭流、数据库连接)
}

示例

java

运行

复制代码
public class ExceptionDemo {
    public static void main(String[] args) {
        int a = 10;
        int b = 0;
        
        try {
            // 可能抛出算术异常的代码
            int result = a / b;
            System.out.println("结果:" + result);
        } catch (ArithmeticException e) {
            // 捕获并处理异常
            System.out.println("错误:除数不能为 0");
            // 打印异常详细信息(调试用)
            e.printStackTrace();
        } finally {
            // 无论是否异常,都会执行
            System.out.println("程序执行完毕");
        }
    }
}

输出

plaintext

复制代码
错误:除数不能为 0
java.lang.ArithmeticException: / by zero
	at ExceptionDemo.main(ExceptionDemo.java:8)
程序执行完毕
2. 声明抛出异常(throws)

如果方法内部不想处理异常,可声明 "抛出",由调用者处理:

java

运行

复制代码
import java.io.FileReader;
import java.io.IOException;

// 声明抛出受检异常 IOException
public class ThrowsDemo {
    public static void readFile() throws IOException {
        // 读取文件可能抛出 IOException
        FileReader fr = new FileReader("test.txt");
        fr.close();
    }

    public static void main(String[] args) {
        try {
            // 调用者必须处理抛出的异常
            readFile();
        } catch (IOException e) {
            System.out.println("文件读取失败:" + e.getMessage());
        }
    }
}
3. 主动抛出异常(throw)

手动触发异常(常用于业务逻辑校验):

java

运行

复制代码
public class ThrowDemo {
    public static void checkAge(int age) {
        if (age < 18) {
            // 主动抛出运行时异常
            throw new IllegalArgumentException("年龄必须≥18");
        }
        System.out.println("年龄合法");
    }

    public static void main(String[] args) {
        try {
            checkAge(16);
        } catch (IllegalArgumentException e) {
            System.out.println("错误:" + e.getMessage());
        }
    }
}

三、自定义异常

当系统内置异常无法满足业务需求时,可自定义异常:

步骤:
  1. 继承 Exception(受检)或 RuntimeException(非受检);
  2. 提供无参构造和带消息的构造方法。

示例

java

运行

复制代码
// 自定义受检异常
public class AgeException extends Exception {
    // 无参构造
    public AgeException() {
        super();
    }

    // 带异常信息的构造
    public AgeException(String message) {
        super(message);
    }
}

// 使用自定义异常
public class CustomExceptionDemo {
    public static void checkAge(int age) throws AgeException {
        if (age < 0 || age > 150) {
            throw new AgeException("年龄必须在 0-150 之间");
        }
        System.out.println("年龄有效");
    }

    public static void main(String[] args) {
        try {
            checkAge(200);
        } catch (AgeException e) {
            System.out.println("异常:" + e.getMessage());
        }
    }
}

四、异常处理的最佳实践

  1. 不要捕获 Throwable(包含 Error,无法处理);
  2. 避免空的 catch 块(会隐藏错误);
  3. 优先捕获具体异常(而非直接捕获 Exception);
  4. finally 中避免抛出异常(会覆盖原异常);
  5. 受检异常用于 "可恢复的错误",非受检异常用于 "编程错误"。

总结

  1. Java 异常根类是 Throwable,核心分支为 Error(不可处理)和 Exception(可处理),Exception 又分受检(编译时处理)和非受检(运行时处理);
  2. 异常处理的核心方式:try-catch-finally(捕获处理)、throws(声明抛出)、throw(主动抛出);
  3. 自定义异常需继承 ExceptionRuntimeException,用于适配业务场景的错误提示。
相关推荐
毕设源码-赖学姐1 小时前
【开题答辩全过程】以 高校资源共享平台的设计与实现 为例,包含答辩的问题和答案
java
Coding茶水间2 小时前
基于深度学习的管道缺陷检测系统演示与介绍(YOLOv12/v11/v8/v5模型+Pyqt5界面+训练代码+数据集)
开发语言·人工智能·深度学习·yolo·机器学习
shamalee2 小时前
MS SQL Server partition by 函数实战二 编排考场人员
java·服务器·开发语言
aisifang002 小时前
MS SQL Server partition by 函数实战三 成绩排名
java
listhi5202 小时前
基于MATLAB的汽车电动助力转向系统(EPS)转向特性分析
开发语言·matlab·汽车
C++chaofan2 小时前
JUC 并发编程:对可见性、有序性与 volatile的理解
java·开发语言·spring·java-ee·juc·synchronized·
无名-CODING2 小时前
Tomcat 底层核心知识点字典(面试必备)
java·面试·tomcat
csbysj20202 小时前
Django ORM - 单表实例
开发语言
XiYang-DING2 小时前
【Java SE】双亲委派模型
java·开发语言