Flyinsky's Codes
1394 字
7 分钟
异常处理及自定义异常
2024-10-14

Java异常处理与如何自定义异常#

在Java编程中,异常处理是一个核心组成部分,用于管理运行时错误,保证程序的健壁性与安全性。本篇博客将深入探讨Java中的异常处理机制,并指导如何自定义异常,以满足特定的业务需求。

Java异常的基本概念#

在Java中,异常(Exception)被用来表示程序运行过程中出现的非正常情况,比如用户输入错误、文件未找到、网络连接失败等。Java的异常处理机制基于三个关键词:try, catch, 和 finally

  • try块: 将可能抛出异常的代码包裹在try块中。
  • catch块: 当try块中的代码抛出异常时,catch块会被执行,用来捕捉异常并进行相应处理。
  • finally块: 无论是否捕获到异常,finally块中的代码总会被执行,常用于资源释放操作。

异常分类#

Java中的异常分为两大类:检查型异常(checked exceptions)非检查型异常(unchecked exceptions)

  • 检查型异常: 在编译时必须处理的异常(例如 IOException, SQLException等)。
  • 非检查型异常: 包括运行时异常(例如 NullPointerException, IndexOutOfBoundsException等)和错误(例如 OutOfMemoryError, StackOverflowError等)。

自定义异常#

在实际开发中,使用Java内置的异常类型可能无法完全满足需求。这时候,我们就需要定义自己的异常类。自定义异常可以提供更丰富的错误信息,并能更好地与业务逻辑结合。

步骤 1: 定义异常类#

自定义异常类通常是ExceptionRuntimeException的子类。选择继承哪一个,取决于你想定义的是检查型异常还是非检查型异常。

// 检查型自定义异常
public class BusinessException extends Exception {
    public BusinessException(String message) {
        super(message);
    }
}

// 非检查型自定义异常
public class BusinessException extends RuntimeException {
    public BusinessException(String message) {
        super(message);
    }
}

步骤 2: 抛出异常#

在你的业务代码中,当某个条件不满足时,可以抛出上面定义的异常。

public void processOrder(Order order) throws BusinessException {
    if (order.getItems().size() == 0) {
        throw new BusinessException("订单不能为空");
    }
    // 其他逻辑处理
}

步骤 3: 捕获并处理异常#

在调用可能抛出自定义异常的方法时,使用try-catch结构来捕获并处理异常。

try {
    orderProcessor.processOrder(myOrder);
} catch (BusinessException e) {
    System.out.println("处理订单时发生错误:" + e.getMessage());
}

常见异常#

  • RuntimeException
    • java.lang.ArrayIndexOutOfBoundsException 数组索引越界异常。当对数组的索引值为负数或大于等于数组大小时抛出。
    • java.lang.ArithmeticException 算术条件异常。譬如:整数除零等。
    • java.lang.NullPointerException 空指针异常。当应用试图在要求使用对象的地方使用了null时,抛出该异常。譬如:调用null对象的实例方法、访问null对象的属性、计算null对象的长度、使用throw语句抛出null等等。
    • java.lang.ClassNotFoundException 找不到类异常。当应用试图根据字符串形式的类名构造类,而在遍历CLASSPAH之后找不到对应名称的class文件时,抛出该异常。
    • java.lang.NegativeArraySizeException 数组长度为负异常
    • java.lang.ArrayStoreException 数组中包含不兼容的值抛出的异常
    • java.lang.SecurityException 安全性异常
    • java.lang.IllegalArgumentException 非法参数异常
  • IOException
    • IOException:操作输入流和输出流时可能出现的异常。
    • EOFException 文件已结束异常
    • FileNotFoundException 文件未找到异常
  • 其他
    • ClassCastException 类型转换异常类
    • ArrayStoreException 数组中包含不兼容的值抛出的异常
    • SQLException 操作数据库异常类
    • NoSuchFieldException 字段未找到异常
    • NoSuchMethodException 方法未找到抛出的异常
    • NumberFormatException 字符串转换为数字抛出的异常
    • StringIndexOutOfBoundsException 字符串索引超出范围抛出的异常
    • IllegalAccessException 不允许访问某类异常
    • InstantiationException 当应用程序试图使用Class类中的newInstance()方法创建一个类的实例,而指定的类对象无法被实例化时,抛出该异常

实践:自定义邮箱地址格式异常,检查邮箱地址是否合法#

为了创建用于检查电子邮件地址格式是否合法的自定义异常,我们可以继承Java的Exception类。下面是一个名为InvalidEmailException的自定义异常类的示例,这个异常类将用于在电子邮件格式不符合预期的情况下抛出异常。

自定义异常类:InvalidEmailException#

public class InvalidEmailException extends Exception {
    // 构造函数,允许传入错误信息
    public InvalidEmailException(String message) {
        super(message);
    }
}

接下来,我们创建一个工具方法validateEmail来检查电子邮件地址是否合法。我将使用一个简单的正则表达式来验证电子邮件的格式,如果电子邮件不符合格式,则抛出我们自定义的InvalidEmailException

import java.util.regex.Pattern;

public class EmailValidator {

    // 正则表达式来检验邮箱格式
    private static final String EMAIL_REGEX = "^[a-zA-Z0-9_+&*-]+(?:\\.[a-zA-Z0-9_+&*-]+)*@(?:[a-zA-Z0-9-]+\\.)+[a-zA-Z]{2,7}$";

    public static void validateEmail(String email) throws InvalidEmailException {
        // 使用 Pattern 和 Matcher 类来检查邮箱格式
        if (email == null || !Pattern.matches(EMAIL_REGEX, email)) {
            throw new InvalidEmailException("Email address is invalid: " + email);
        }
    }

    public static void main(String[] args) {
        try {
            EmailValidator.validateEmail("w2084151024@gmail.com");
            System.out.println("电子邮箱地址合法");
        } catch (InvalidEmailException e) {
            System.out.println(e.getMessage());
        }

        try {
            EmailValidator.validateEmail("abcabcabc");
            System.out.println("电子邮箱地址不合法");
        } catch (InvalidEmailException e) {
            System.out.println(e.getMessage());
        }
    }
}

在这个示例中,EmailValidator类包含了一个validateEmail方法,它使用正则表达式来检查输入的电子邮件是否符合标准格式。如果不符合,方法会抛出InvalidEmailException。在main方法中,我们针对有效和无效的电子邮件地址分别测试了这个方法。