Java 异常处理

JavaJavaBeginner
立即练习

💡 本教程由 AI 辅助翻译自英文原版。如需查看原文,您可以 切换至英文原版

简介

在本实验中,我们将探索 Java 异常处理(Java Exception Handling),这是 Java 编程中的一个关键概念,它允许你管理代码中的错误和意外情况。通过优雅地处理错误而不是让程序崩溃,异常处理有助于使你的程序更加健壮和用户友好。

我们将涵盖以下主题:

  1. 理解什么是异常以及它们的重要性
  2. 使用 try-catch 块来处理异常
  3. 创建和抛出自定义异常
  4. 使用 finally 块进行清理操作
  5. 处理多个 catch 块

在本实验结束时,你将能够编写能够处理各种错误场景的 Java 程序,从而使你的代码更加可靠和易于维护。


Skills Graph

%%%%{init: {'theme':'neutral'}}%%%% flowchart RL java(("`Java`")) -.-> java/DataStructuresGroup(["`Data Structures`"]) java(("`Java`")) -.-> java/ObjectOrientedandAdvancedConceptsGroup(["`Object-Oriented and Advanced Concepts`"]) java/DataStructuresGroup -.-> java/arrays("`Arrays`") java/ObjectOrientedandAdvancedConceptsGroup -.-> java/classes_objects("`Classes/Objects`") java/ObjectOrientedandAdvancedConceptsGroup -.-> java/inheritance("`Inheritance`") java/ObjectOrientedandAdvancedConceptsGroup -.-> java/exceptions("`Exceptions`") subgraph Lab Skills java/arrays -.-> lab-413830{{"`Java 异常处理`"}} java/classes_objects -.-> lab-413830{{"`Java 异常处理`"}} java/inheritance -.-> lab-413830{{"`Java 异常处理`"}} java/exceptions -.-> lab-413830{{"`Java 异常处理`"}} end

理解异常

在我们深入探讨如何处理异常之前,先来理解什么是异常以及它们的重要性。

  1. 打开你的终端并导航到项目目录:

    cd ~/project
  2. 在文本编辑器中打开 ExceptionDemo.java。你应该会看到以下基本结构:

    public class ExceptionDemo {
        public static void main(String[] args) {
            // 我们将在步骤 1 中在此处添加代码
        }
    }
  3. 让我们修改这个文件以演示一个异常。将 main 方法的内容替换为以下代码:

    int[] numbers = {1, 2, 3};
    System.out.println("尝试访问数组的第四个元素...");
    System.out.println(numbers[3]);
    System.out.println("由于异常,这行代码不会被执行。");

    这段代码创建了一个包含三个元素的数组,然后尝试访问第四个元素(该元素不存在)。

  4. 保存 ExceptionDemo.java 文件。

  5. 编译并运行程序:

    javac ExceptionDemo.java
    java ExceptionDemo

    你应该会看到类似以下的错误信息:

    尝试访问数组的第四个元素...
    Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: Index 3 out of bounds for length 3
        at ExceptionDemo.main(ExceptionDemo.java:5)

这是一个异常的示例。由于我们尝试访问一个不存在的数组索引,抛出了 ArrayIndexOutOfBoundsException。程序没有继续运行,而是停止并提供了有关错误的信息。

异常是 Java 处理错误和异常情况的方式。它们允许我们:

  • 识别并响应代码中的错误
  • 将错误处理代码与常规代码分离,使两者更易于理解
  • 将错误信息传播到调用堆栈中

在接下来的步骤中,我们将学习如何处理这些异常,以使我们的程序更加健壮。

使用 try-catch 块

现在我们已经理解了什么是异常,接下来让我们学习如何使用 try-catch 块来处理它们。

  1. 再次在文本编辑器中打开 ExceptionDemo.java

  2. main 方法的内容替换为以下代码:

    int[] numbers = {1, 2, 3};
    
    try {
        System.out.println("尝试访问第四个元素...");
        System.out.println(numbers[3]);
        System.out.println("如果发生异常,这行代码不会被执行。");
    } catch (ArrayIndexOutOfBoundsException e) {
        System.out.println("哎呀!发生了一个错误: " + e.getMessage());
        System.out.println("该数组只有 " + numbers.length + " 个元素。");
    }
    
    System.out.println("程序在处理异常后继续运行。");

    让我们分解一下这段代码:

    • try 块包含可能抛出异常的代码。
    • catch 块指定它可以处理的异常类型(在本例中为 ArrayIndexOutOfBoundsException),并提供在发生该异常时要执行的代码。
    • 如果 try 块中发生异常,执行会立即跳转到 catch 块。
    • 在 catch 块执行后,程序会继续执行 try-catch 结构之后的代码。
  3. 保存 ExceptionDemo.java 文件。

  4. 编译并运行程序:

    javac ExceptionDemo.java
    java ExceptionDemo

    你应该会看到类似以下的输出:

    尝试访问第四个元素...
    哎呀!发生了一个错误: Index 3 out of bounds for length 3
    该数组只有 3 个元素。
    程序在处理异常后继续运行。

这展示了 try-catch 块如何让我们优雅地处理异常。程序没有崩溃,而是提供了有用的信息并继续运行。

创建和抛出自定义异常

有时,你可能希望创建自己的异常类型来处理程序中的特定情况。让我们看看如何创建和抛出自定义异常。

  1. 在文本编辑器中打开 CustomException.java。你会看到它目前是空的。

  2. 添加以下代码来定义我们的自定义异常:

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

    这段代码创建了一个名为 CustomException 的新异常类型,它继承了内置的 Exception 类。

  3. 现在,打开 CustomExceptionDemo.java。你应该会看到以下基本结构:

    public class CustomExceptionDemo {
        public static void main(String[] args) {
            // 我们将在步骤 3 中在此处添加代码
        }
    }
  4. 让我们修改这个文件以使用我们的自定义异常。将内容替换为以下代码:

    public class CustomExceptionDemo {
        public static void validateAge(int age) throws CustomException {
            if (age < 0) {
                throw new CustomException("年龄不能为负数");
            } else if (age > 120) {
                throw new CustomException("年龄似乎不现实");
            }
            System.out.println("年龄有效: " + age);
        }
    
        public static void main(String[] args) {
            try {
                System.out.println("验证年龄 25:");
                validateAge(25);
                System.out.println("验证年龄 -5:");
                validateAge(-5);
            } catch (CustomException e) {
                System.out.println("捕获到 CustomException: " + e.getMessage());
            }
    
            System.out.println("程序在异常处理后继续运行");
        }
    }

    这段代码展示了:

    • 如何创建一个抛出自定义异常的方法(validateAge
    • 如何使用 throw 关键字抛出异常
    • 如何捕获和处理自定义异常
  5. 保存 CustomException.javaCustomExceptionDemo.java 两个文件。

  6. 编译并运行程序:

    javac CustomException.java CustomExceptionDemo.java
    java CustomExceptionDemo

    你应该会看到类似以下的输出:

    验证年龄 25:
    年龄有效: 25
    验证年龄 -5:
    捕获到 CustomException: 年龄不能为负数
    程序在异常处理后继续运行

这个示例展示了如何使用自定义异常来处理程序中的特定错误条件。它们允许你创建更有意义的错误信息,并以不同的方式处理不同类型的错误。

使用 finally 块

finally 块用于执行无论是否抛出异常都应该运行的代码。它通常用于清理操作。

  1. 打开 FinallyDemo.java。你应该会看到以下基本结构:

    public class FinallyDemo {
        public static void main(String[] args) {
            // 我们将在步骤 4 中在此处添加代码
        }
    }
  2. main 方法的内容替换为以下代码:

    try {
        System.out.println("尝试除以零...");
        int result = 10 / 0;
        System.out.println("这行代码不会被执行。");
    } catch (ArithmeticException e) {
        System.out.println("捕获到一个异常: " + e.getMessage());
    } finally {
        System.out.println("无论是否发生异常,这个块都会执行。");
    }
    
    System.out.println("程序在 try-catch-finally 块后继续运行。");

    这段代码展示了:

    • 一个尝试除以零的 try 块(这将抛出 ArithmeticException
    • 一个用于处理异常的 catch 块
    • 一个无论是否发生异常都会执行的 finally 块
  3. 保存 FinallyDemo.java 文件。

  4. 编译并运行程序:

    javac FinallyDemo.java
    java FinallyDemo

    你应该会看到类似以下的输出:

    尝试除以零...
    捕获到一个异常: / by zero
    无论是否发生异常,这个块都会执行。
    程序在 try-catch-finally 块后继续运行。

finally 块对于无论是否抛出异常都应该执行的清理操作非常有用,例如关闭文件或网络连接。

使用多个 catch 块

有时,同一段代码中可能会发生不同类型的异常。Java 允许你使用多个 catch 块来处理不同的异常类型。

  1. 打开 MultipleCatchDemo.java。你应该会看到以下基本结构:

    public class MultipleCatchDemo {
        public static void main(String[] args) {
            // 我们将在步骤 5 中在此处添加代码
        }
    }
  2. main 方法的内容替换为以下代码:

    try {
        int[] numbers = {1, 2, 3};
        int index = 4; // 这将导致 ArrayIndexOutOfBoundsException
        int result = numbers[index] / 0; // 如果执行到这行,将抛出 ArithmeticException
        System.out.println("这行代码不会被执行。");
    } catch (ArithmeticException e) {
        System.out.println("捕获到 ArithmeticException: " + e.getMessage());
    } catch (ArrayIndexOutOfBoundsException e) {
        System.out.println("捕获到 ArrayIndexOutOfBoundsException: " + e.getMessage());
    } catch (Exception e) {
        System.out.println("捕获到通用异常: " + e.getMessage());
    }
    
    System.out.println("程序在异常处理后继续运行。");

    这段代码展示了:

    • 使用多个 catch 块来处理不同类型的异常
    • catch 块的顺序很重要:更具体的异常应该先于更通用的异常捕获
  3. 保存 MultipleCatchDemo.java 文件。

  4. 编译并运行程序:

    javac MultipleCatchDemo.java
    java MultipleCatchDemo

    你应该会看到类似以下的输出:

    捕获到 ArrayIndexOutOfBoundsException: Index 4 out of bounds for length 3
    程序在异常处理后继续运行。

请注意,尽管我们的代码中有两个潜在的异常(除以零和数组索引越界),但只有 ArrayIndexOutOfBoundsException 被捕获,因为它首先发生。如果将 index 变量更改为 2,你将看到 ArithmeticException 被捕获。

总结

在本实验中,我们探索了 Java 异常处理,这是编写健壮且可靠的 Java 程序的关键部分。我们涵盖了几个重要概念:

  1. 理解异常:我们学习了什么是异常,以及它们如何帮助管理代码中的错误。
  2. 使用 try-catch 块:我们了解了如何使用 try-catch 块优雅地处理异常,使程序在发生错误时仍能继续运行。
  3. 创建和抛出自定义异常:我们创建了自己的异常类型,并学习了如何抛出异常以表示特定的错误条件。
  4. 使用 finally 块:我们学习了如何使用 finally 块来执行无论是否发生异常都应运行的代码,这对于清理操作非常有用。
  5. 使用多个 catch 块:我们了解了如何使用多个 catch 块处理不同类型的异常,从而实现更具体的错误处理。

这些异常处理技术是 Java 程序员工具箱中的必备工具。它们使你能够编写更具弹性的代码,优雅地处理意外情况,从而提高程序的整体可靠性和用户体验。

在你继续 Java 学习的过程中,你会发现有效的异常处理是编写专业质量代码的关键部分。在你的程序中练习使用这些技术,你将很快成为一名熟练的 Java 开发者!

请记住,如果你觉得某些概念具有挑战性,这是完全正常的——异常处理可能很复杂,尤其是对初学者而言。继续练习,如果需要更多解释,不要犹豫回顾本实验或寻找其他资源。你越频繁地使用异常处理,它们在编码过程中就会变得越自然。

您可能感兴趣的其他 Java 教程