在 Java 中处理异常的 9 个最佳实践(一)
Java 中的异常处理不是一个简单的话题。 初学者会发现很难理解,即使是经验丰富的开发人员也会花费数小时来讨论应该如何以及应该抛出或处理哪些 Java 异常。
这就是为什么大多数开发团队都有自己的一套关于如何使用它们的规则。
如果您是团队的新手,您可能会惊讶于这些规则与您之前使用的规则有多么不同。
尽管如此,还是有一些最佳实践被大多数团队使用。 今天的帖子将向大家展示九个最重要的方法,大家可以使用它们来开始或改进异常处理。
不过,在深入探讨之前,我们将快速介绍异常本身的概念。
- 什么是异常和异常处理?
- 为什么我们需要它们?
回答完这些问题后,我们就可以讨论最佳实践了。 当然,如果想直接跳到最佳实践本身,您可以单击此处。
异常和异常处理:简介
什么是异常处理? 什么是异常?
在深入研究我们的异常最佳实践列表之前,我们需要了解这些东西是什么以及我们使用它们的目的。
定义异常
那么,什么是异常?
简而言之,异常是程序执行过程中的异常情况。
出现问题时会发生异常。 试图打开一个文件,但它不存在? 你有一个异常。 试图在对象上调用方法但变量为空?
异常是不应该发生的坏事。 但既然它们确实发生了,我们就需要处理它们。 而这种“处理”就是我们所说的异常处理。
异常处理是一种错误处理机制。 当出现问题时,会抛出异常。 如果我们什么都不做,异常会导致我们的应用程序崩溃。
或者我们可以选择处理异常。 也就是说,承认问题已经发生,防止应用程序崩溃,并采取必要的步骤以便从错误中恢复或优雅地失败。
常用的错误处理
正如大家刚刚读到的,异常处理是一种错误处理机制,但它不是唯一的。
如今
,绝大多数编程语言都将异常处理作为一项功能提供,但情况并非总是如此。
没有异常的语言如何处理错误?
一种流行的方法是返回错误代码。例如,假设您有一个 C 函数,它接受一个整数数组和一个整数,然后搜索并返回与指定数字匹配的第一个项目的索引。
当在数组中找不到该项目时该怎么办?一个流行的选择是返回 -1。
这种方法的优点是使代码易于推理:不会中断和跳转代码。只是很好的旧函数返回值。
另一方面,这种错误处理策略鼓励函数的使用者始终检查错误值。
这些验证的绝对数量会使代码受到污染。许多防御性检查可能会隐藏重要的业务逻辑,从而降低代码的可读性和可维护性。
错误代码的另一个严重缺点是它们缺乏上下文。我们可能知道代码“-5”表示未找到某个文件……但是哪个文件呢?整数不能轻易携带该信息。
这种方法的另一个问题是,有时我们无法返回值(例如,考虑构造函数)。初始化对象时出错了?有了错误代码,你就束手无策了。
恢复异常
异常的出现是为了解决刚刚读到的问题。
当抛出异常时,程序的控制流就会中断。如果没有人处理异常,就会导致程序崩溃。
用户将看到异常的消息,他们很可能不会理解。该消息甚至可能未本地化为他们的语言。
简而言之,这不是很好的用户体验。
所以
,你会想要处理异常(即使它只是为了记录问题,显示更用户友好的错误消息,然后无论如何退出应用程序)。
要处理抛出的异常,我们必须捕获它。我们通过使用异常处理块来做到这一点。
当我们捕获异常时,程序的流程控制被处理到异常处理块。在那里,我们可以进行必要的安排以处理异常。
听起来还是太抽象了?继续阅读。当我们了解 Java 异常的细节时,我们将看到实际的例子。
Java 异常是如何工作的:一个简单的例子
考虑以下代码:
package com.company;
import java.io.*;
public class Main {
public static void main(String[] args){
System.out.println("First line");
System.out.println("Second line");
System.out.println("Third line");
int[] myIntArray = new int[]{1, 2, 3};
print4thItemInArray(myIntArray);
System.out.println("Fourth line");
System.out.println("Fith line");
}
private static void print4thItemInArray(int[] arr) {
System.out.println(arr[3]);
System.out.println("Fourth element successfully displayed!");
}
}
上面的代码打印了一些无害的消息,只说明它们是哪一行。
打印第三行后,代码用三个整数初始化一个数组,并将其作为参数传递给私有方法。 该方法尝试打印数组中不存在的第四项。 这会导致抛出
ArrayIndexOutOfBoundsException
异常。
发生这种情况时,程序的执行将停止并显示异常消息。 永远不会显示第四条和第五条消息。 print4thItemInArray()
方法的第二行都没有执行。
这是结果输出:
现在,让我们更改示例,添加一些异常处理:
package com.company;
import java.io.*;
public class Main {
public static void main(String[] args) {
// write your code here
System.out.println("First line");
System.out.println("Second line");
System.out.println("Third line");
try {
int[] myIntArray = new int[]{1, 2, 3};
print4thItemInArray(myIntArray);
} catch (ArrayIndexOutOfBoundsException e){
System.out.println("The array doesn't have four items!");
}
System.out.println("Fourth line");
System.out.println("Fith line");
}
private static void print4thItemInArray(int[] arr) {
System.out.println(arr[3]);
}
}
现在,运行代码后,这是我们得到的输出:
这一次,异常仍然发生,和以前一样。 私有方法的执行立即停止——这就是“Fourth element successfully displayed! ”这一行没有显示的原因。 然后将程序的流程控制交给
catch
块。 在catch
块内,代码仅打印一条消息,说明该数组没有四个项目。 然后,恢复执行。
我们刚刚介绍的只是冰山一角。
当涉及到在 Java 中处理异常时,除了我们的简短介绍之外还有很多内容。
相关文章
在 Java 中获取文件大小
发布时间:2023/05/01 浏览次数:139 分类:Java
-
Java 提供了不同的方法来获取文件的字节大小。 本教程演示了在 Java 中获取文件大小的不同方法。使用 Java IO 的文件类获取文件大小 Java IO 包的 File 类提供了以字节为单位获取文件大小的功能。
Java 中的文件分隔符
发布时间:2023/05/01 浏览次数:108 分类:Java
-
本篇文章介绍了 Java 中的文件分隔符。Java 中的文件分隔符 文件分隔符是用来分隔目录的字符; 例如,Unix 使用 /,Windows 使用 \ 作为文件分隔符。
Java 中的文件过滤器
发布时间:2023/05/01 浏览次数:193 分类:Java
-
本篇文章介绍如何在 Java 中使用 FileFilter。FileFilter 用于过滤具有特定扩展名的文件。 Java内置包IO和Apache Commons IO为FileFilter提供了类和接口来进行文件过滤操作。
Java 获取 ISO 8601 格式的当前时间戳
发布时间:2023/05/01 浏览次数:132 分类:Java
-
本篇文章介绍了 ISO 8601 日期格式、其重要性及其在 Java 中的使用。 它还列出了一些优点来强调为什么应该使用 ISO 格式来表示日期。
在 Java 中获取数组的子集
发布时间:2023/05/01 浏览次数:142 分类:Java
-
本篇文章介绍了几种在 Java 中获取数组子集的方法。使用 Arrays.copyOf() 方法获取数组的子集 使用 Arrays.copyOfRange() 方法获取数组的子集
用 Java 填充二维数组
发布时间:2023/05/01 浏览次数:110 分类:Java
-
二维数组是基于表结构的,即行和列,填充二维数组不能通过简单的添加到数组操作来完成。 本篇文章介绍如何在 Java 中填充二维数组。
计算 Java 数组中的重复元素
发布时间:2023/05/01 浏览次数:202 分类:Java
-
本篇文章介绍Java计算数组中重复元素的方法。计算 Java 数组中的重复元素。我们可以创建一个程序来计算数组中的重复元素。 该数组可以是未排序的,也可以是已排序的。
Java 中 List 和 Arraylist 的区别
发布时间:2023/05/01 浏览次数:90 分类:Java
-
表示为单个单元的一组单个对象称为集合。 在 Java 中,Collection 是一个具有多个已定义接口和类的框架,用于将一组对象表示为一个单元。 它允许我们操纵