java中的异常包含哪些?

    在 Java 中,异常(Exception)是程序运行时出现的非预期情况,会中断正常执行流程。Java 异常体系以 
Throwable
 为根类,分为 
Error
(错误)
 和 
Exception
(异常)
 两大分支,各自包含不同类型的异常情况。以下是详细讲解:

一、异常体系结构



Throwable(所有异常/错误的根类)
├─ Error(错误):JVM 无法处理的严重问题,程序通常无法恢复
│  ├─ VirtualMachineError(虚拟机错误)
│  │  ├─ OutOfMemoryError(OOM,内存溢出)
│  │  └─ StackOverflowError(栈溢出)
│  ├─ NoClassDefFoundError(类定义未找到,运行时类缺失)
│  └─ AWTError(GUI 组件错误,如图形环境异常)
│
└─ Exception(异常):程序可处理的问题,分两类
   ├─ 受检异常(Checked Exception):编译期必须处理(捕获或声明抛出)
   │  ├─ IOException(I/O 操作异常)
   │  │  ├─ FileNotFoundException(文件未找到)
   │  │  └─ EOFException(文件读取到末尾)
   │  ├─ SQLException(数据库操作异常)
   │  ├─ ClassNotFoundException(反射时类未找到)
   │  └─ InterruptedException(线程被中断异常)
   │
   └─ 非受检异常(Unchecked Exception):编译期无需处理,运行时可能出现
      ├─ RuntimeException(运行时异常,非受检异常的核心)
      │  ├─ NullPointerException(空指针异常,调用 null 对象的方法/属性)
      │  ├─ IndexOutOfBoundsException(索引越界,如数组/集合下标超范围)
      │  │  ├─ ArrayIndexOutOfBoundsException(数组索引越界)
      │  │  └─ StringIndexOutOfBoundsException(字符串索引越界)
      │  ├─ ClassCastException(类型转换异常,如将 String 强转为 Integer)
      │  ├─ ArithmeticException(算术异常,如除以 0)
      │  ├─ IllegalArgumentException(参数非法,如传递不符合要求的参数)
      │  └─ NumberFormatException(数字格式异常,如 "abc" 转 int)
      │
      └─ 其他非 RuntimeException 的非受检异常(极少,如 ThreadDeath)

二、核心分类详解

1. Error(错误)

本质:由 JVM 生成,代表系统级的严重错误,超出程序本身的处理能力,通常是不可恢复的。

特点:程序无需捕获或处理(也无法有效处理),需通过修改代码或调整环境解决。

常见类型:

     
StackOverflowError
:栈内存溢出,通常因递归调用无终止条件(每次递归都会占用栈空间)。



public void recursive() {
    recursive(); // 无限递归,最终抛出 StackOverflowError
}


OutOfMemoryError
(OOM)
:堆内存溢出,如创建大量对象且未被垃圾回收(如循环创建对象存入集合)。


NoClassDefFoundError
:编译时存在的类,运行时因类路径错误或类被删除而无法找到。

2. Exception(异常

程序可通过代码处理的异常,分为 受检异常 和 非受检异常,核心区别在于编译期是否强制检查。

(1)受检异常(Checked Exception)

       定义:所有非 
RuntimeException
 及其子类的异常,编译期必须显式处理(捕获或声明抛               出),否则编译报错。

       设计目的:提醒开发者处理可预见的外部依赖风险(如文件操作、网络请求可能失败)。

       常见类型及场景:


IOException
:I/O 操作相关异常,如文件读写、网络传输失败。

子类 
FileNotFoundException
:试图读取不存在的文件时抛出。

SQLException
:数据库操作异常,如连接失败、SQL 语法错误、表不存在等。
ClassNotFoundException
:通过反射(如 
Class.forName("com.example.User")
)加载类时,类未找到。
InterruptedException
:线程在休眠(
sleep
)或等待(
wait
)时被其他线程中断。

处理示例

必须通过 
try-catch
 捕获或 
throws
 声明,否则编译不通过:



// 编译报错:未处理 IOException
public void readFile() {
    FileReader fr = new FileReader("test.txt"); // FileReader 构造方法声明抛出 IOException
}
 
// 正确处理方式 1:声明抛出
public void readFile() throws IOException {
    FileReader fr = new FileReader("test.txt");
}
 
// 正确处理方式 2:捕获并处理
public void readFile() {
    try {
        FileReader fr = new FileReader("test.txt");
    } catch (IOException e) {
        System.out.println("文件读取失败:" + e.getMessage());
    }
}
(2)非受检异常(Unchecked Exception)

        定义
RuntimeException
 及其子类(或特殊的非 
Exception
 类型,如 
ThreadDeath
),编           译期不强制处理,运行时才可能抛出。

       设计目的:通常由程序逻辑错误导致,应通过代码优化避免(而非依赖 
try-catch
)。

       常见类型及场景

       Nu
llPointerException
(NPE)
:最常见异常,当调用 
null
 对象的方法或属性时抛出。



String s = null;
s.length(); // 抛出 NPE,因 s 为 null

        I
ndexOutOfBoundsException
:索引超出容器范围(如数组、
ArrayList

String
)。



int[] arr = new int[3];
arr[5] = 10; // 数组索引越界(ArrayIndexOutOfBoundsException)

        C
lassCastException
:类型强制转换失败,如将父类对象转为不兼容的子类。



Object obj = "hello";
Integer num = (Integer) obj; // 抛出 ClassCastException(String 不能转 Integer)

          A
rithmeticException
:算术运算错误,典型场景是除以 0。


int result = 10 / 0; // 抛出 ArithmeticException

           I
llegalArgumentException
:方法接收非法参数,如传递负数给要求正数的方法。



public void setAge(int age) {
    if (age < 0) {
        throw new IllegalArgumentException("年龄不能为负数");
    }
}

           N
umberFormatException
:字符串转数字失败(如非数字字符串转 
int
)。


Integer.parseInt("abc"); // 抛出 NumberFormatException

三、异常处理机制

Java 通过 
try-catch-finally

throws

throw
 关键字实现异常处理:


try
:包裹可能抛出异常的代码块。
catch
:捕获并处理指定类型的异常(可多个 
catch
 块,按 “子类在前、父类在后” 顺序排列)。
finally
:无论是否发生异常,都会执行(常用于释放资源,如关闭文件流、数据库连接)。
throws
:在方法声明处标注可能抛出的异常,由调用者处理。
throw
:主动抛出异常对象(如检测到非法参数时)。

示例:



public int divide(int a, int b) {
    if (b == 0) {
        throw new ArithmeticException("除数不能为 0"); // 主动抛出异常
    }
    return a / b;
}
 
public static void main(String[] args) {
    try {
        int result = new Demo().divide(10, 0);
        System.out.println("结果:" + result);
    } catch (ArithmeticException e) {
        System.out.println("捕获异常:" + e.getMessage()); // 处理异常
    } finally {
        System.out.println("无论是否异常,都会执行"); // 释放资源等操作
    }
}
// 输出:
// 捕获异常:除数不能为 0
// 无论是否异常,都会执行

四、总结

Error:严重错误,程序无法处理,需通过代码优化或环境调整避免(如避免内存泄漏、控制递归深度)。受检异常:编译期强制处理,与外部交互相关(如文件、数据库),需显式捕获或声明。非受检异常:运行时异常,多为逻辑错误(如 NPE、索引越界),应通过代码健壮性避免。

合理使用异常处理可提高程序稳定性,但需避免滥用(如用异常代替正常逻辑判断、捕获所有异常),同时注意资源释放(推荐使用 try-with-resources 自动关闭资源)。

© 版权声明
THE END
如果内容对您有所帮助,就支持一下吧!
点赞0 分享
Ahywon的头像 - 鹿快
评论 抢沙发

请登录后发表评论

    暂无评论内容