【Java】异常详解+实例演示+知识总结

一、介绍

本文介绍Java中的异常相关知识,通过实例演示异常的出现和解决方法,以及异常的体系结构、核心语法、注意事项等,下面将进行详细解析。

**二、**Java 异常核心语法

1.try-catch-finally:捕获并处理异常

java 复制代码
try {
    // 可能抛出异常的代码
} catch (异常类型1 e) {
    // 处理异常类型1
} catch (异常类型2 e) { // 多个catch需按"从小到大"(子类在前)
    // 处理异常类型2
} finally {
    // 无论是否异常,必执行(除非JVM退出)
}

2.throw:手动抛出异常

java 复制代码
if (参数不合法) {
    throw new IllegalArgumentException("参数错误"); // 手动抛异常
}

3.throws:声明方法可能抛出的异常

java 复制代码
public void readFile() throws IOException { // 声明可能抛IOException
    // 读取文件(可能触发IOException)
}

4.try-with-resources:自动关闭资源(实现AutoCloseable接口)

java 复制代码
try (FileReader fr = new FileReader("test.txt")) { // 资源自动关闭
    fr.read();
} catch (IOException e) {
    e.printStackTrace();
}

**三、**常见异常示例及解决

1.NullPointerException(空指针异常)

场景:调用 null 对象的方法或属性。

解决:

2. IndexOutOfBoundsException(索引越界)

场景 :数组 / 集合索引超出范围(如ArrayIndexOutOfBoundsExceptionStringIndexOutOfBoundsException)。

数组示例

解决:

集合示例

解决:

3. ClassCastException(类型转换异常)

场景:强制转换不兼容的类型。

解决:

4. ArithmeticException(算术异常)

场景:除以 0 等非法算术操作。

解决:

5. IllegalArgumentException(非法参数异常)

场景:方法接收的参数不符合预期(如参数为负数但业务要求必须为正数)。

6. IOException(IO 异常,Checked 异常)

场景:文件读写等 IO 操作失败。

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

public class IOExceptionDemo {
    // 方法1:用throws声明异常(交给调用者处理)
    public static void readFile1() throws IOException {
        FileReader fr = new FileReader("nonexistent.txt"); // 文件不存在时抛IOException
        fr.close();
    }

    // 方法2:用try-catch处理异常
    public static void readFile2() {
        try (FileReader fr = new FileReader("nonexistent.txt")) { // try-with-resources自动关闭
            fr.read();
        } catch (IOException e) {
            System.out.println("IO异常:" + e.getMessage());
        }
    }

    public static void main(String[] args) {
        try {
            readFile1(); // 调用声明throws的方法,必须处理
        } catch (IOException e) {
            e.printStackTrace();
        }
        readFile2(); // 已内部处理,无需额外操作
    }
}

四、异常相关知识问题

1. Checked 异常和 Unchecked 异常的区别?
  • Checked 异常 :继承自Exception(非RuntimeException),编译时强制处理(try-catchthrows),如IOException
  • Unchecked 异常 :继承自RuntimeException,编译时不强制处理,通常是代码逻辑错误(如空指针),运行时触发。
2. finalfinallyfinalize的区别?
  • final:修饰符,可修饰类(不可继承)、方法(不可重写)、变量(不可修改)。
  • finally:异常处理块,与try搭配,无论是否抛出异常都会执行(除非 JVM 退出),常用于释放资源。
  • finalizeObject类的方法,垃圾回收前调用,用于资源清理(不推荐使用,Java 9 后标记为过时)。
3. try-catch-finallyreturn的执行顺序?
  • trycatch中的return会先执行,但结果会暂存,然后执行finally
  • finally中也有return,会覆盖try/catch的返回值。
4. throwthrows的区别?
  • throw:用于方法内部,手动抛出具体异常对象(如throw new IOException())。
  • throws:用于方法声明处,声明方法可能抛出的异常类型(如public void m() throws IOException),告知调用者需处理。
5. 异常处理的最佳实践?
  • 避免捕获所有异常(catch (Exception e)),应捕获具体异常。
  • 不要忽略异常(空catch块),至少记录日志。
  • try-with-resources自动关闭资源(替代finally手动关闭)。
  • 异常信息需具体(包含上下文,如 "文件 xxx 不存在")。
  • 自定义异常时,区分 Checked/Unchecked(业务异常推荐 Unchecked)。

五、异常体系结构与概括

1. 异常体系结构

bash 复制代码
Throwable(顶层类)
├─ Error(错误:JVM层面的严重问题,程序无法处理)
│  ├─ VirtualMachineError(虚拟机错误)
│  │  ├─ OutOfMemoryError(内存溢出)
│  │  ├─ StackOverflowError(栈溢出)
│  │  └─ InternalError(内部错误)
│  ├─ AWTError(AWT组件错误)
│  └─ LinkageError(类链接错误)
│     ├─ NoClassDefFoundError(类定义未找到)
│     └─ UnsatisfiedLinkError(本地方法链接失败)
│
└─ Exception(异常:程序可处理的问题)
   ├─ RuntimeException(运行时异常:非检查型,编译不强制处理)
   │  ├─ NullPointerException(空指针)
   │  ├─ IndexOutOfBoundsException(索引越界)
   │  ├─ ClassCastException(类型转换)
   │  ├─ IllegalArgumentException(非法参数)
   │  ├─ ArithmeticException(算术错误)
   │  └─ ConcurrentModificationException(并发修改)
   │
   └─ 受检异常(Checked Exception:编译强制处理)
      ├─ IOException(IO操作异常)
      │  ├─ FileNotFoundException(文件未找到)
      │  └─ IOException(通用IO错误)
      ├─ SQLException(数据库操作异常)
      ├─ ClassNotFoundException(类未找到)
      └─ InterruptedException(线程中断)

2. Error(错误):不可处理的严重问题

错误类型 含义 常见场景 解决方式
OutOfMemoryError 内存溢出(JVM 堆 / 方法区不足) 创建大量对象未释放、大文件加载 1. 调大 JVM 内存参数(-Xms/-Xmx)2. 优化对象生命周期,避免内存泄漏
StackOverflowError 栈溢出(方法调用栈深度超过限制) 递归调用无终止条件、多层嵌套方法 1. 修复递归终止条件2. 减少方法嵌套层级
NoClassDefFoundError 运行时找不到类定义(编译存在,运行缺失) 类路径(classpath)配置错误、jar 包缺失 1. 检查类路径是否包含目标类2. 确保依赖 jar 包存在
UnsatisfiedLinkError 本地方法(JNI)链接失败 调用的本地库(.dll/.so)不存在或版本不匹配 1. 检查本地库路径是否正确2. 确保库文件与系统兼容

3. Exception(异常):可处理的问题

3.1 运行时异常(RuntimeException):非检查型异常

特点:编译时不强制处理,通常由程序逻辑错误导致,需通过代码优化避免。

异常类型 含义 常见场景 解决方式
NullPointerException 调用 null 对象的方法 / 属性 String s = null; s.length(); 1. 调用前判空(if (obj != null))2. 使用Optional类避免空指针
IndexOutOfBoundsException 数组 / 集合索引越界 List<String> list = new ArrayList<>(); list.get(0); 1. 访问前检查索引范围(index < size)2. 使用循环时避免硬编码索引
ClassCastException 类型强制转换失败 Object obj = "str"; Integer i = (Integer) obj; 1. 转换前用instanceof判断类型2. 避免无意义的强制转换
IllegalArgumentException 方法接收非法参数 传入负数到要求正数的方法(如new ArrayList(-1) 1. 方法内校验参数合法性2. 调用前确保参数符合要求
ArithmeticException 算术错误(如除以 0) int a = 1 / 0; 1. 避免除数为 02. 计算前校验除数合法性
ConcurrentModificationException 迭代集合时并发修改(如边遍历边删除) for (String s : list) { list.remove(s); } 1. 使用迭代器的remove()方法2. 使用CopyOnWriteArrayList等线程安全集合
3.2 受检异常(Checked Exception):编译时强制处理

特点:编译器要求必须捕获或声明抛出,通常由外部环境导致(如 IO、网络问题)。

异常类型 含义 常见场景 解决方式
IOException IO 操作失败(读 / 写文件、网络流) 读取不存在的文件、网络中断时写数据 1. 捕获异常并处理(如提示 "文件不存在")2. 确保资源路径正确,网络通畅
FileNotFoundException 找不到指定文件 / 目录(IOException子类) new FileInputStream("不存在的文件.txt") 1. 检查文件路径是否正确2. 操作前判断文件是否存在(file.exists()
SQLException 数据库操作失败 连接参数错误、SQL 语法错误、表不存在 1. 检查数据库连接配置和 SQL 语句2. 打印异常信息定位具体错误(如e.getMessage()
ClassNotFoundException 加载类时找不到类定义(与NoClassDefFoundError的区别:前者是主动加载失败,后者是被动引用失败) Class.forName("com.mysql.Driver") 1. 检查类全限定名是否正确2. 确保依赖的 jar 包已引入
InterruptedException 线程在等待 / 休眠时被中断 Thread.sleep(1000)时调用thread.interrupt() 1. 捕获后可恢复中断状态(Thread.currentThread().interrupt())2. 根据业务决定是否终止线程
相关推荐
她说人狗殊途2 小时前
面试题001
java
Han.miracle2 小时前
Java的多线程——多线程(3)线程安全
java·开发语言·jvm·学习·安全·线程·多线程
大象席地抽烟2 小时前
spring中使用rabbitmq(spring-boot-starter-amqp)
java
运维_攻城狮2 小时前
Nexus 3.x 私服搭建与运维完全指南(Maven 实战)
java·运维·maven
R.lin2 小时前
mmap内存映射文件
java·后端
chxii2 小时前
Maven 详解(中)
java·maven
SimonKing2 小时前
消息积压、排查困难?Provectus Kafka UI 让你的数据流一目了然
java·后端·程序员
考虑考虑2 小时前
点阵图更改背景文字
java·后端·java ee
ZHE|张恒2 小时前
Spring Boot 3 + Flyway 全流程教程
java·spring boot·后端