【Java】 异常讲解

本文详细介绍了Java中的异常处理机制,包括异常的定义、关键字try、catch、finally的使用,异常层次结构,以及如何创建和处理异常。异常处理使得程序在遇到错误时能够优雅地处理并继续运行,提高了代码的健壮性。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

Java 异常讲解

异常 是一种特殊的机制,可以让我们在程序中处理错误。

什么是异常

在编程世界中,程序执行中的错误和不可预见的情况称为 异常

在程序中,由于 用户操作无效磁盘空间不足与服务器的网络连接丢失 ,可能会发生异常。异常也可能是由 编程错误不正确使用 API 引起的。与现实世界中的人类不同,程序必须确切地知道如何处理这些情况。为此,Java 有一种称为异常处理的机制。

关于关键字

**Java 中的异常处理基于在程序中使用以下关键字:**在 Java 程序中使用关键字的示例:

  • try - 定义可能发生异常的代码块;
  • catch - 定义处理异常的代码块;
  • finally - 定义一个可选的代码块,如果存在,则执行该代码块,而不管 try 块的结果如何。

这些关键字用于在代码中创建特殊构造:try{}catch try{}catch{}finally try{}finally{}

  • throw - 用于提出异常;
  • throws - 在方法签名中使用,以警告方法可能引发异常。
// 此方法从键盘读取字符串

public String input() throws MyException { // Use throws to warn
	// t该方法可能引发 MyException
    BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));
    String s = null;
    // 我们使用 try 块包装可能会创建异常的代码。在这种情况下,
    // 编译器告诉我们
    // BufferedReader 类可能引发 I/O 异常
    try {
        s = reader.readLine();
	// 我们使用 catch 块包装处理 IOException 的代码
    } catch (IOException e) {
        System.out.println(e.getMessage());
	// 我们在 finally 块中关闭读取流
    } finally {
	// 例如,如果流没有打开,那么当我们关闭流时可能会发生异常,因此我们将代码包装在一个 try 块中
        try {
            reader.close();
	// 关闭读取流时处理异常
        } catch (IOException e) {
            System.out.println(e.getMessage());
        }
    }

    if (s.equals("")) {
    // 当存在空字符串时,将阻止我们的程序正常工作。
    // 例如,我们使用此方法的结果调用子字符串 (1, 2) 方法。因此,我们必须通过使用 throw 来生成我们自己的 MyException 异常类型来中断程序。
        throw new MyException("The string cannot be empty!");
    }
    return s;
}

为什么我们需要异常?

让我们看一个来自现实世界的例子。想象一下,高速公路的一段有一座重量容量有限的小桥。如果一辆比桥梁极限重的汽车驶过它,它可能会倒塌。委婉地说,司机的情况会变得异常。为了避免这种情况,运输部门在出现问题之前在道路上安装警告标志。看到警告标志,驾驶员将他或她的车辆重量与桥梁的最大重量进行比较。如果车辆太重,驾驶员将采取绕行路线。运输部门首先,使卡车司机能够在必要时改变路线,其次,警告司机主要道路上的危险,第三,警告司机在一定条件下不得使用桥梁。防止和解决程序中异常情况的能力,允许它继续运行,是在 Java 中使用异常的一个原因。

异常机制 还允许您通过验证(检查)任何输入来保护 代码(API) 免受不当使用。现在想象一下,你是运输部门。首先,您需要知道驾驶者可以预期遇到麻烦的地方。其次,您需要创建并安装警告标志。最后,如果主要路线出现问题,您需要提供绕行。

Java 中, 异常机制 的工作方式与此类似。在开发过程中,我们使用 try 模块围绕危险的代码段构建 “异常屏障” ,我们使用 catch 模块提供 “备份路由” ,并且我们编写代码,无论模块中有什么内容,都应该运行。如果我们不能提供“备份路由”,或者我们想给用户选择的权利,我们至少必须警告他或她危险。

为什么?想象一下,一个司机的愤怒,他没有看到一个警告标志,到达了一座他无法穿过的小桥!

在编程中,在编写类和方法时,我们不能总是预见其他开发人员如何使用它们。因此,我们无法预见 100% 解决特殊情况的正确方法 。也就是说,警告其他人发生特殊情况的可能性是一种很好的形式。而 Java异常机制 允许我们使用 关键字 来做到这一点,其本质上是一个声明,即我们方法的一般行为包括抛出异常。

因此,任何使用该方法的人都知道他或她应该编写代码来处理异常。

公路

try catch {} finally{} throws

警告他人 “麻烦” (throws Exception)

如果您不打算在方法中处理异常,但希望警告其他人可能会发生异常,请使用关键字。方法签名中的此关键字意味着,在某些情况下,方法可能会引发异常。

此警告是方法接口的一部分,允许其用户实现自己的异常处理逻辑。抛出后,我们指定抛出的异常类型。

这些通常是 Java 类的后代。由于 Java 是一种面向对象的语言,因此所有例外都是 Java 中的对象。

告警

异常层次结构

当程序运行时发生错误时,JVM 会从 Java 异常层次结构(一组可能源自共同祖先的异常)类中创建一个适当类型的对象。我们可以将异常运行时情况分为两组:Throwable

  1. 程序无法恢复并继续正常运行的情况。
  2. 可以恢复的情况。

第一组包括涉及从类中继承的异常的情况。这些是由于 JVM 故障内存溢出系统故障 而发生的错误。它们通常表示软件无法修复的严重问题。

Java 中,编译器不会检查此类异常的可能性,因此它们被称为 未经检查的 异常。此组还包括 RuntimeExceptions,它们是从类中降下来的异常,由 JVM 在运行时生成。它们通常是由编程错误引起的。

这些异常也不会在编译时选中(取消选中),因此您无需编写代码来处理它们。

第二组包括编写程序时可以预见的异常情况(因此您应该编写代码来处理它们)。此类异常称为已检查异常。当涉及到异常时,Java 开发人员的大部分工作都是处理这种情况。Error Exception

创建例外 (throw)

当程序运行时,异常由 JVM 或使用语句手动生成。发生这种情况时,将在内存中创建异常对象,程序的主流被中断,并且 JVM 的异常处理程序尝试处理异常。

异常处理

Java 中,我们创建代码块,在其中我们预测需要使用 , , 和 构造进行异常处理。当在块中引发异常时,JVM 会在下一个模块中查找适当的异常处理程序。

如果模块具有所需的异常处理程序,则控制权将传递给它。如果不是,则 JVM 会进一步向下查找模块链,直到找到合适的处理程序。执行模块后,控制权将转移到可选模块。如果未找到合适的模块,则 JVM 将停止程序并显示(当前方法调用堆栈),如果存在该块,则在首先执行该模块后显示该模块。

异常处理示例: 以下是该方法的结果:

通常用于关闭任何流并释放在模块中打开/分配的任何资源。但是,在编写程序时,并不总是能够跟踪所有资源的关闭。为了使我们的生活更轻松,Java 的开发人员提供了该结构,该结构会自动关闭块中打开的任何资源。由于 版本7 中引入了 Java 功能,我们还可以将捕获异构异常组合到一个块中,使代码更加紧凑和可读。

例:

  • try{} catch
  • try{} catch{} finally
  • try{} finally{}

异常

public class Print {

     void print(String s) {
        if (s == null) {
            throw new NullPointerException("Exception: s is null!");
        }
        System.out.println("Inside print method: " + s);
    }

    public static void main(String[] args) {
        Print print = new Print();
        List list= Arrays.asList("first step", null, "second step");

        for (String s : list) {
            try {
                print.print(s);
            }
            catch (NullPointerException e) {
                System.out.println(e.getMessage());
                System.out.println("Exception handled. The program will continue");
            }
            finally {
                System.out.println("Inside finally block");
            }
            System.out.println("The program is running...");
            System.out.println("-----------------");
        }

    }
}

main

Inside print method: first step
Inside finally block
The program is running...
-----------------
Exception: s is null!
Exception handled. The program will continue
Inside finally block
The program is running...
-----------------
Inside print method: second step
Inside finally block
The program is running...
-----------------

finally try try-with-resources try try-with-resources

public String input() throws MyException {
    String s = null;
    try (BufferedReader reader = new BufferedReader(new InputStreamReader(System.in))){
        s = reader.readLine();
   } catch (IOException e) {
       System.out.println(e.getMessage());
   }
    if (s.equals("")) {
        throw new MyException ("The string cannot be empty!");
    }
    return s;
}
public String input() {
    String s = null;
    try (BufferedReader reader = new BufferedReader(new InputStreamReader(System.in))) {
        s = reader.readLine();
        if (s.equals("")) {
            throw new MyException("The string cannot be empty!");
        }
    } catch (IOException | MyException e) {
        System.out.println(e.getMessage());
    }
    return s;
}

底线

通过在 Java 中使用异常,您可以通过创建 “备份路由” 使程序更加健壮,使用 catch 块将主代码与异常处理代码分开,并使用将异常处理的责任转移给使用您的方法的任何人。throws

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

Warolitbos

如果有帮助,请我喝咖啡!

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

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

打赏作者

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

抵扣说明:

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

余额充值