前言:

        在日常开发中,程序在运行时总会遇到各种“意外”——数据格式不对,内存溢出......这些“意外”在Java中被称为异常。如何处理异常呢?本文将带你系统学习Java异常处理机制,涵盖异常概念,体系结构,处理方式,自定义异常等核心内容。

目录

前言:

一.异常的概念与体系结构

1.1什么是异常?

1.2异常体系结构

1.3异常分类

二.异常的处理方式

2.1防御式编程

2.2关键字

三.异常的使用

3.1抛出异常:throw

3.2声明异常:throws

3.3捕获异常:try-catch-finally

四.异常处理流程

五.自定义异常类

5.1为什么需要自定义异常?

5.2实现方式

5.3使用自定义异常

六.总结


一.异常的概念与体系结构

1.1什么是异常?

        异常(Exception)是程序执行过程中发生的不正常行为,它会打断程序的正常执行流程。比如:

System.out.println(10 / 0);  // 算术异常
int[] arr = new int[3];
System.out.println(arr[100]); // 数组越界异常
String str = null;
System.out.println(str.length()); // 空指针异常

Java为每种异常提供了对应的类来描述,比如:ArrayIndexOutOfBoundsException,NullPointerException

1.2异常体系结构

Throwable
├── Error(不可处理的严重问题)
│   ├── StackOverflowError
│   └── OutOfMemoryError
└── Exception(可通过代码处理的异常)
    ├── 受查异常(Checked Exception)
    │   ├── IOException
    │   ├── SQLException
    │   └── ClassNotFoundException
    └── 非受查异常(Unchecked Exception / RuntimeException)
        ├── NullPointerException
        ├── ArrayIndexOutOfBoundsException
        └── ArithmeticException

Error:JVM内部错误,程序无法处理,如栈溢出,内存耗尽。

Exception:程序可以捕获并处理的异常,是我们日常开发的重点。

1.3异常分类

类型 时机 示例 是否必须处理
受查异常 编译时 IOException

必须处理(try-catch

或throws)

非受查异常 运行时 NullPointerException 不强制处理

二.异常的处理方式

2.1防御式编程

        LBYL(事前防御):在操作前做充分检查。缺点:正常流程和错误处理混在一起,代码混乱

        EAFP(事后认错):先操作,遇到问题再处理。Java的异常处理机制就是基于此思想

2.2关键字

关键字 作用
throw 手动抛出异常对象
throws 声明方法可能抛出的异常
try 包裹可能抛出异常的代码
catch 捕获并处理异常
finally 无论是否发生异常都会执行的代码块

三.异常的使用

3.1抛出异常:throw

public static int getElement(int[] array, int index) {
    if (array == null) {
        throw new NullPointerException("数组为空");
    }
    if (index < 0 || index >= array.length) {
        throw new ArrayIndexOutOfBoundsException("下标越界");
    }
    return array[index];
}

注意:throw后的代码不会执行。

3.2声明异常:throws

public void openFile(String path) throws FileNotFoundException {
    if (!path.equals("config.ini")) {
        throw new FileNotFoundException("文件不存在");
    }
}

声明多个异常用逗号隔开。

如有父子关系,可声明父类异常。

调用方不许处理或继续抛出。

3.3捕获异常:try-catch-finally

try {
    openFile("test.txt");
} catch (FileNotFoundException e) {
    e.printStackTrace();
} finally {
    System.out.println("资源释放");
}

try中抛出异常后的代码不会执行

多个catch按顺序匹配,子类异常在前,父类在后。

finally块一定会执行(除非System.exit())。

finally中的return会覆盖try/catch中的return,应避免。

四.异常处理流程

        try → 发生异常 → 匹配catch → 执行finally → 继续执行后续代码(若无异常继续抛出)

如果始终未处理,最终由JVM处理,程序终止。

五.自定义异常类

5.1为什么需要自定义异常?

        内置异常无法描述业务场景,比如“用户名错误”,“密码错误”等。

5.2实现方式

        1.继承Exception(受查异常)或RuntimeException(非受查异常)。

        2.提供给带String参数的构造方法

class UserNameException extends Exception {
    public UserNameException(String message) {
        super(message);
    }
}

class PasswordException extends Exception {
    public PasswordException(String message) {
        super(message);
    }
}

5.3使用自定义异常

public void login(String name, String pwd) throws UserNameException, PasswordException {
    if (!"admin".equals(name)) {
        throw new UserNameException("用户名错误");
    }
    if (!"123456".equals(pwd)) {
        throw new PasswordException("密码错误");
    }
}

六.总结

        Java异常分为Error和Exception,Exception又分为受查异常和非受查异常。

        使用try-catch-finally捕获处理异常,使用throw主动抛出异常

        finally用于资源释放,throws用于声明异常。

        自定义异常继承Exception或RuntimeException

Logo

汇聚全球AI编程工具,助力开发者即刻编程。

更多推荐