Checked and Unchecked Exceptions in Java – Java中已检查和未检查的异常情况

最后修改: 2019年 8月 27日

中文/混合/英文(键盘快捷键:t)

1. Overview

1.概述

Java exceptions fall into two main categories: checked exceptions and unchecked exceptions.

Java异常主要分为两类。已检查的异常和未检查的异常

In this tutorial, we’ll provide some code samples on how to use them.

在本教程中,我们将提供一些关于如何使用它们的代码样本。

2. Checked Exceptions

2.被检查的异常情况

In general, checked exceptions represent errors outside the control of the program. For example, the constructor of FileInputStream throws FileNotFoundException if the input file does not exist.

一般来说,检查过的异常代表程序控制之外的错误。例如,FileInputStream的构造函数抛出FileNotFoundException,如果输入文件不存在。

Java verifies checked exceptions at compile-time.

Java在编译时验证了被检查的异常。

Therefore, we should use the throws keyword to declare a checked exception:

因此,我们应该使用throws关键字来声明一个被检查的异常。

private static void checkedExceptionWithThrows() throws FileNotFoundException {
    File file = new File("not_existing_file.txt");
    FileInputStream stream = new FileInputStream(file);
}

We can also use a try-catch block to handle a checked exception:

我们也可以使用一个try-catch块来处理一个被检查的异常。

private static void checkedExceptionWithTryCatch() {
    File file = new File("not_existing_file.txt");
    try {
        FileInputStream stream = new FileInputStream(file);
    } catch (FileNotFoundException e) {
        e.printStackTrace();
    }
}

Some common checked exceptions in Java are IOException, SQLException and ParseException.

Java中一些常见的检查异常IOExceptionSQLExceptionParseException

The Exception class is the superclass of checked exceptions, so we can create a custom checked exception by extending Exception:

Exception类是检查性异常的超类,所以我们可以通过扩展Exception创建一个自定义的检查性异常

public class IncorrectFileNameException extends Exception {
    public IncorrectFileNameException(String errorMessage) {
        super(errorMessage);
    }
}

3. Unchecked Exceptions

3.未被检查的异常情况

If a program throws an unchecked exception, it reflects some error inside the program logic.

如果一个程序抛出一个未检查的异常,它反映了程序逻辑内部的一些错误。

For example, if we divide a number by 0, Java will throw ArithmeticException:

例如,如果我们用一个数字除以0,Java会抛出ArithmeticException

private static void divideByZero() {
    int numerator = 1;
    int denominator = 0;
    int result = numerator / denominator;
}

Java does not verify unchecked exceptions at compile-time. Furthermore, we don’t have to declare unchecked exceptions in a method with the throws keyword. And although the above code does not have any errors during compile-time, it will throw ArithmeticException at runtime.

Java在编译时不会验证未检查的异常。此外,我们不需要在方法中用throws关键字来声明未检查的异常。而且,尽管上述代码在编译时没有任何错误,但它在运行时将抛出ArithmeticException

Some common unchecked exceptions in Java are NullPointerException, ArrayIndexOutOfBoundsException and IllegalArgumentException.

Java中一些常见的未经检查的异常NullPointerExceptionArrayIndexOutOfBoundsExceptionIllegalArgumentException

The RuntimeException class is the superclass of all unchecked exceptions, so we can create a custom unchecked exception by extending RuntimeException:

RuntimeException类是所有未经检查的异常的超类,因此我们可以通过扩展RuntimeException创建一个自定义的未经检查的异常。

public class NullOrEmptyException extends RuntimeException {
    public NullOrEmptyException(String errorMessage) {
        super(errorMessage);
    }
}

4. When to Use Checked Exceptions and Unchecked Exceptions

4.何时使用检查过的例外和未检查过的例外

It’s a good practice to use exceptions in Java so that we can separate error-handling code from regular code. However, we need to decide which type of exception to throw. The Oracle Java Documentation provides guidance on when to use checked exceptions and unchecked exceptions:

在Java中使用异常是一种很好的做法,这样我们就可以把处理错误的代码和常规代码分开。然而,我们需要决定抛出哪种类型的异常。Oracle Java文档提供了关于何时使用有检查的异常和无检查的异常的指导。

“If a client can reasonably be expected to recover from an exception, make it a checked exception. If a client cannot do anything to recover from the exception, make it an unchecked exception.”

“如果客户可以合理地期望从一个异常中恢复过来,那就把它变成一个被检查的异常。如果客户不能做任何事情来恢复这个异常,就把它变成一个未检查的异常”。

For example, before we open a file, we can first validate the input file name. If the user input file name is invalid, we can throw a custom checked exception:

例如,在我们打开一个文件之前,我们可以首先验证输入的文件名。如果用户输入的文件名是无效的,我们可以抛出一个自定义的检查异常。

if (!isCorrectFileName(fileName)) {
    throw new IncorrectFileNameException("Incorrect filename : " + fileName );
}

In this way, we can recover the system by accepting another user input file name.

通过这种方式,我们可以通过接受另一个用户输入的文件名来恢复系统。

However, if the input file name is a null pointer or it is an empty string, it means that we have some errors in the code. In this case, we should throw an unchecked exception:

然而,如果输入的文件名是一个空指针或它是一个空字符串,这意味着我们在代码中存在一些错误。在这种情况下,我们应该抛出一个未经检查的异常。

if (fileName == null || fileName.isEmpty())  {
    throw new NullOrEmptyException("The filename is null or empty.");
}

5. Conclusion

5.总结

In this article, we discussed the difference between checked and unchecked exceptions. We also provided some code examples to show when to use checked or unchecked exceptions.

在这篇文章中,我们讨论了检查过的异常和未检查过的异常之间的区别。我们还提供了一些代码实例来说明何时使用检查过的或未检查过的异常。

As always, all code in this article can be found over on GitHub.

一如既往,本文中的所有代码都可以在GitHub上找到over