授课语音

Java中的异常分类与自定义异常

Java中的异常机制是非常重要的编程概念,它帮助我们捕获和处理运行时错误,确保程序的健壮性与可靠性。本节课将深入探讨Java中的异常分类、如何自定义异常以及自定义异常的应用。


1. 异常概述

异常是指在程序执行过程中出现的意外情况或错误,通常会导致程序的执行中断。Java通过Throwable类及其子类来处理异常。

1.1 Throwable类

在Java中,所有异常类都继承自Throwable类。Throwable类有两个主要的子类:

  • Exception:程序可以处理的异常(可检查异常)。
  • Error:程序无法处理的严重问题(如OutOfMemoryError等)。

2. Java中的异常分类

Java中的异常分为两大类:检查异常(Checked Exceptions)和运行时异常(Unchecked Exceptions)。

2.1 检查异常(Checked Exceptions)

检查异常是指在编译时必须处理的异常,通常由程序员明确处理或者通过throws关键字声明抛出。常见的检查异常有:IOExceptionSQLException等。

示例:IOException

import java.io.File;
import java.io.FileReader;
import java.io.IOException;

public class CheckedExceptionExample {
    public static void main(String[] args) {
        try {
            File file = new File("example.txt");
            FileReader fr = new FileReader(file); // 可能会抛出IOException
        } catch (IOException e) {
            // 处理IOException异常
            System.out.println("文件读取错误:" + e.getMessage());
        }
    }
}

代码解析:

  • 在使用FileReader时,可能会发生IOException,所以必须用try-catch块来捕获该异常。

2.2 运行时异常(Unchecked Exceptions)

运行时异常是指在程序运行时出现的异常,通常是由程序员的逻辑错误导致的,这类异常继承自RuntimeException类。常见的运行时异常有:NullPointerExceptionArrayIndexOutOfBoundsException等。

示例:NullPointerException

public class UncheckedExceptionExample {
    public static void main(String[] args) {
        String str = null;
        try {
            // 会抛出NullPointerException
            System.out.println(str.length());
        } catch (NullPointerException e) {
            // 处理NullPointerException异常
            System.out.println("空指针异常:" + e.getMessage());
        }
    }
}

代码解析:

  • 在对null对象进行操作时会抛出NullPointerException,程序员应避免对null对象进行调用。

2.3 Error类

Error类表示严重的错误,通常不由程序员处理,且不会通过异常捕获。常见的错误有:OutOfMemoryErrorStackOverflowError等。

示例:StackOverflowError

public class ErrorExample {
    public static void main(String[] args) {
        // 会导致StackOverflowError
        recursiveMethod();
    }

    public static void recursiveMethod() {
        recursiveMethod(); // 无限递归
    }
}

代码解析:

  • 该示例会导致StackOverflowError,通常是由于程序进入无限递归或栈溢出导致的错误。

3. 自定义异常

在实际开发中,我们有时需要根据业务需求定义自定义异常,以便更好地捕获和处理特定的错误场景。

3.1 自定义检查异常

检查异常继承自Exception类,可以通过throws关键字声明抛出。

示例:自定义检查异常

// 自定义检查异常
public class InvalidAgeException extends Exception {
    public InvalidAgeException(String message) {
        super(message); // 调用父类的构造方法传入异常信息
    }
}

public class CustomCheckedExceptionExample {
    public static void main(String[] args) {
        try {
            validateAge(-5); // 传入非法年龄,抛出自定义异常
        } catch (InvalidAgeException e) {
            // 处理自定义异常
            System.out.println("捕获异常:" + e.getMessage());
        }
    }

    // 验证年龄方法
    public static void validateAge(int age) throws InvalidAgeException {
        if (age < 0) {
            throw new InvalidAgeException("年龄不能为负数!");
        }
        System.out.println("年龄验证通过!");
    }
}

代码解析:

  • InvalidAgeException继承自Exception,是一个自定义的检查异常。
  • validateAge方法会抛出自定义异常InvalidAgeException,如果年龄小于0,则抛出该异常。

3.2 自定义运行时异常

运行时异常继承自RuntimeException类,通常不需要显式声明抛出。

示例:自定义运行时异常

// 自定义运行时异常
public class InvalidParameterException extends RuntimeException {
    public InvalidParameterException(String message) {
        super(message); // 调用父类构造方法
    }
}

public class CustomUncheckedExceptionExample {
    public static void main(String[] args) {
        try {
            validateParameter(0); // 传入无效参数,抛出自定义异常
        } catch (InvalidParameterException e) {
            // 处理自定义运行时异常
            System.out.println("捕获异常:" + e.getMessage());
        }
    }

    // 验证参数方法
    public static void validateParameter(int param) {
        if (param <= 0) {
            throw new InvalidParameterException("参数必须大于零!");
        }
        System.out.println("参数验证通过!");
    }
}

代码解析:

  • InvalidParameterException继承自RuntimeException,是一个自定义的运行时异常。
  • validateParameter方法会抛出自定义运行时异常InvalidParameterException,如果参数小于等于0。

4. 自定义异常的使用场景

自定义异常可以在多个场景中使用,常见的场景有:

  • 业务逻辑错误:如用户输入的年龄不合法、商品库存不足等。
  • 数据校验:如数据格式错误、字段缺失等。
  • 服务异常:如服务调用失败、服务超时等。

4.1 业务逻辑错误示例

public class OrderService {
    public void placeOrder(int productId, int quantity) throws ProductOutOfStockException {
        if (quantity > 100) {
            throw new ProductOutOfStockException("库存不足!");
        }
        // 执行其他订单处理逻辑
    }
}

代码解析:

  • 在订单服务中,如果订单数量超过100,则抛出自定义的ProductOutOfStockException异常。

4.2 数据校验错误示例

public class UserService {
    public void createUser(String username) throws InvalidUsernameException {
        if (username == null || username.isEmpty()) {
            throw new InvalidUsernameException("用户名不能为空!");
        }
        // 执行其他用户创建逻辑
    }
}

代码解析:

  • 在用户服务中,如果用户名为空,则抛出自定义的InvalidUsernameException异常。

5. 总结

Java的异常机制是为了提高程序的健壮性和可维护性。通过了解和掌握异常的分类,我们能够更好地捕获和处理各种异常。自定义异常能够帮助我们根据业务需求定义更具可读性和可维护性的错误处理机制。

在本节课中,我们学习了:

  • Java中的异常分类:检查异常、运行时异常和错误。
  • 如何自定义异常,包括自定义检查异常和自定义运行时异常。
  • 自定义异常的实际应用场景。
去1:1私密咨询

系列课程: