【Java笔记】第14章:异常

在这里插入图片描述

上期回顾: 【Java笔记】第13章:集合
个人主页:C_GUIQU
归属专栏:Java

在这里插入图片描述

正文

1. 异常的概念

异常是指程序运行过程中出现的非正常情况。当异常出现时,程序会执行一段预先准备好的代码来进行处理,这种处理有助于减少用户的损失,并为用户提供提示信息。

2. 异常的分类

Java 中的所有错误或异常都继承自 Throwable 类,位于 java.lang 包中。

2.1 Throwable

Throwable 类是 Java 中所有异常和错误的父类,包含以下常用方法:

  • String getMessage():获取字符串类型的异常信息,用于向用户展示提示。
  • void printStackTrace():输出详细的异常信息,用于编程人员调试。

2.2 Error

Error 类是 Throwable 的子类,代表程序无法自行恢复的严重错误,例如 JVM 内存不足或栈溢出。通常情况下,这类错误不应该通过程序代码进行捕获和处理。

例子:栈溢出错误

public class StackOverflowExample {
    public void recursiveMethod() {
        recursiveMethod(); // 递归调用导致栈溢出
    }
    
    public static void main(String[] args) {
        new StackOverflowExample().recursiveMethod();
    }
}

2.3 Exception

Exception 类也是 Throwable 的子类,代表可以通过代码处理的异常。分为以下两类:

2.3.1 RuntimeException(运行时异常)

这类异常在编译时不会被检测,但可能在运行时出现,例如:

  • java.lang.ArrayIndexOutOfBoundsException:数组下标越界
  • java.lang.NullPointerException:空指针异常
  • java.lang.ClassCastException:类型转换异常
  • java.lang.NumberFormatException:数字格式转换异常

例子:空指针异常

public class NullPointerExample {
    public static void main(String[] args) {
        String str = null;
        System.out.println(str.length()); // 会引发 NullPointerException
    }
}

2.3.2 非RuntimeException(已检查异常)

这类异常在编译时必须被处理,例如 Class.forName() 可能抛出的异常。

例子:已检查异常

public class CheckedExceptionExample {
    public static void main(String[] args) {
        try {
            Class.forName("com.example.NonExistentClass");
        } catch (ClassNotFoundException e) {
            e.printStackTrace(); // 捕获并处理异常
        }
    }
}

3. 异常的产生

3.1 自动产生异常

程序在运行过程中,遇到错误代码会自动产生异常,一旦出现异常,程序会被终止,无法继续执行后续代码。

3.2 手动产生异常

使用 throw 关键字可以在代码中手动产生异常,用于在特定条件下结束程序的执行。

public class ThrowExample {
    public static void main(String[] args) {
        int age = -5;
        if (age < 0) {
            throw new IllegalArgumentException("年龄不能为负数");
        }
    }
}

4. 异常的传递

Java 中的异常沿着方法的调用链进行反方向传递,最终传递给 JVM,导致程序终止。

5. 异常的处理

5.1 消极处理异常(声明异常)

使用 throws 关键字在方法声明中消极处理异常,推卸异常处理的责任,但程序依然会因异常而终止。

public void riskyMethod() throws IOException {
    // 方法可能抛出 IOException
}

5.2 积极处理异常(捕获异常)

使用 try-catch 结构捕获和处理异常。

public class TryCatchExample {
    public static void main(String[] args) {
        try {
            int[] numbers = {1, 2, 3};
            System.out.println(numbers[5]);
        } catch (ArrayIndexOutOfBoundsException e) {
            System.out.println("数组下标越界:" + e.getMessage());
        } finally {
            System.out.println("无论是否发生异常,都会执行");
        }
    }
}

注意

  • try 后可以跟多个 catch,用于捕获不同类型的异常。
  • catch 中可以使用父类型异常来处理子类异常。

6. 自定义异常

通过继承 Exception 类或其子类,可以创建自定义异常。如果继承 RuntimeException,则抛出的异常为运行时异常。

例子:自定义异常

public class CustomException extends Exception {
    public CustomException(String message) {
        super(message);
    }
    
    public CustomException() {
        super("自定义异常");
    }
}

public class CustomExceptionTest {
    public static void main(String[] args) {
        try {
            throw new CustomException("这是一个自定义异常");
        } catch (CustomException e) {
            e.printStackTrace();
        }
    }
}

7. 方法覆盖中的异常处理

在方法覆盖(重写)时,子类的方法不能抛出比父类更多或更宽的异常。

例子:方法覆盖中的异常限制**

class Parent {
    public void doSomething() throws IOException {
        // 父类方法抛出 IOException
    }
}

class Child extends Parent {
    @Override
    public void doSomething() throws FileNotFoundException {
        // 子类可以抛出与父类相同或更具体的异常
    }
}

8. 知识拓展

  1. 异常捕获的最佳实践:建议尽量使用具体的异常类型进行捕获,而不是使用通用的 Exception 类。这样可以使代码更加明确,便于维护。
  2. finally 的应用场景finally 块通常用于释放资源,如关闭文件流、数据库连接等,确保资源不会因为异常的发生而无法关闭。
  3. 异常链:可以使用 Throwable.initCause(Throwable) 方法将一个异常作为另一个异常的原因,从而形成异常链,以便于更好地追踪异常的来源。

结语
感谢您的阅读!期待您的一键三连!欢迎指正!
在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Guiat

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值