💎一站式轻松地调用各大LLM模型接口,支持GPT4、智谱、星火、月之暗面及文生图 广告
# Java 受检与非受检的异常 > 原文: [https://howtodoinjava.com/java/exception-handling/checked-vs-unchecked-exceptions-in-java/](https://howtodoinjava.com/java/exception-handling/checked-vs-unchecked-exceptions-in-java/) 在此 Java 异常教程中,了解 Java 中的异常是什么,什么是受检的异常以及它与非受检的异常有何不同。 我们还将学习有关 Java 受检异常的一些最佳实践。 ```java Table of Contents 1\. What is an exception in Java? 2\. Checked vs unchecked exceptions in Java 3\. Java exception handling best practices ``` ## 1\. Java 中有什么异常? > “异常是在程序执行期间发生的意外事件,它破坏了正常的指令流。” 在 Java 中,所有错误和异常都用`Throwable`类表示。 当方法中发生错误时,该方法将创建一个对象(`Throwable`的任何子类型)并将其交给运行时系统。 该对象称为异常对象。 异常对象包含有关错误的信息,包括错误的类型和发生错误时程序的状态。 创建异常对象并将其交给运行时系统称为**引发异常**。 #### 1.1 异常处理 在应用程序中创建异常对象时,我们有两种选择。 * 我们要么在方法中处理它 * 或者我们可以将其传递给调用方方法以使其处理。 在设置方法责任时,这是非常重要的决定。 一种方法应该清楚地表明它将处理所有异常情况,而不会处理哪些异常情况。 它是使用`throws`子句在方法语法中定义的。 要处理异常,我们必须在`try-catch`块的`catch`部分中捕获异常。 > 如果在应用程序中未处理异常,则该异常将传播到 JVM,并且 JVM 通常将终止程序本身。 ## 2\. Java 中的受检与非受检异常 #### 2.1 异常层次 在 Java 中,异常大致分为两部分:**受检异常和非受检的异常**。 ![ExceptionHierarchyJava](https://img.kancloud.cn/bb/08/bb088e79366889ab483f1fb3b6a2fef8_400x325.png) #### 2.2 受检异常 Java 迫使您在应用程序代码中以某种方式处理这些错误情况。 一旦您开始编译程序,它们将立即出现在您的脸上。 您绝对可以忽略它们,而让它们传递给 JVM,但这是一个坏习惯。 理想情况下,您必须在应用程序内部的适当级别上处理这些异常,以便可以通知用户有关失败的信息并要求他重试/稍后再来。 通常,受检异常表示程序无法直接控制的错误情况。 它们通常发生在与外部资源/网络资源例如数据库问题,网络连接错误,文件丢失等 > 受检异常是`Exception`类的子类。 **受检异常**的示例是:`ClassNotFoundException`,`IOException`,`SQLException`等。 ##### 受检异常示例 `FileNotFoundException`是 Java 中的一个受检异常。 任何时候,我们都想从文件系统中读取文件,Java 会强制我们处理文件可能不存在的错误情况。 ```java public static void main(String[] args) { FileReader file = new FileReader("somefile.txt"); } ``` 在上述情况下,您将获得消息 – `Unhandled exception type FileNotFoundException`的编译时错误。 为了使程序能够编译,您必须在`try-catch`块中处理此错误情况。 下面给出的代码将完全可以编译。 ```java public static void main(String[] args) { try { FileReader file = new FileReader("somefile.txt"); } catch (FileNotFoundException e) { //Alternate logic e.printStackTrace(); } } ``` #### 2.3 非受检的异常 Java 还提供了`UncheckedExceptions`,编译器不会检查其出现。 一旦执行了任何错误代码,它们就会生效/出现在您的程序中。 编译器不强制方法声明其实现引发的非受检的异常。 通常,此类方法几乎总是也不会声明它们。 非受检的异常是`RuntimeException`的子类。 **非受检的异常**的示例是:`ArithmeticException`,`ArrayStoreException`,`ClassCastException`等。 “奇怪的是,`RuntimeException`本身是`Exception`的子类,即所有非受检异常类都应该隐式是受检异常,但不是。” ##### 非受检的异常示例 在下面检查给定的代码。 上面的代码没有给出任何编译时错误。 但是当您举这个例子时,它抛出`NullPointerException`。`NullPointerException`是 Java 中非受检的异常。 ```java public static void main(String[] args) { try { FileReader file = new FileReader("pom.xml"); file = null; file.read(); } catch (IOException e) { //Alternate logic e.printStackTrace(); } } ``` 请记住,受检的异常和非受检的异常之间最大的**区别**在于,受检的异常是由编译器强制执行的,用于指示不受程序控制的异常情况(例如,I/O 错误),而非受检的异常在运行时发生,用于指示编程错误(例如,空指针)。 ## 3\. Java 异常处理最佳实践 1. **当方法无法执行其名称所说明的功能时,可以使用受检异常**。 例如预先准备好配置文件并使用配置文件进行配置的名为`prepareSystem()`的方法可以声明抛出`FileNotFoundException`,这意味着该方法使用了文件系统中的配置文件。 2. 理想情况下,绝对不应将受检异常用于编程错误,而在此类情况下,绝对不应将**资源错误**用于流控制。 3. 仅抛出方法无法以任何方式处理的那些异常。 方法应首先尝试在遇到它时立即对其进行处理。 仅当无法处理内部方法时才引发异常。 4. 定义方法签名的一种好方法是在方法名称附近声明异常。 如果您的方法名为`openFile`,则应抛出`FileNotFoundException”`?。 如果您的方法名为`findProvider`,则应抛出`NoSuchProviderException`。 同样,应将这些类型的异常设置为受检异常,因为它会强制调用者处理方法语义所固有的问题。 5. 规则是,如果可以合理地期望客户端从异常中恢复,请将其设置为受检的异常。 如果客户端无法采取任何措施来从异常中恢复,请将其设置为非受检的异常。 实际上,大多数应用程序必须从几乎所有异常中恢复,包括`NullPointerException`,`IllegalArgumentExceptions`和许多其他非受检的异常。 失败的操作/事务将被中止,但应用程序必须保持活动状态并准备为下一个操作/事务提供服务。 通常只有在启动期间关闭应用程序才是合法的。 例如,如果缺少配置文件,并且没有该配置文件,应用程序将无法执行任何明智的操作,则关闭该应用程序是合法的。 ## 4\. 总结 在本文中,我们了解了 Java 中受检异常与非受检异常之间的区别,以及**如何处理非受检异常**(带有示例的 Java 中的异常层次结构)。 随时在评论中提问。 学习愉快! 阅读更多: * [异步和同步异常](//howtodoinjava.com/java/exception-handling/asynchronous-and-synchronous-exceptions-in-java/ "Asynchronous and synchronous exceptions in java") * [使用内部类的异常处理](//howtodoinjava.com/best-practices/best-practices-for-for-exception-handling/ "Best practices for Exception handling") * [异常处理最佳做法](//howtodoinjava.com/best-practices/java-exception-handling-best-practices/ "Java exception handling best practices") * [有效处理`NullPointerException`](//howtodoinjava.com/java/exception-handling/how-to-effectively-handle-nullpointerexception-in-java/ "How to effectively handle NullPointerException in java") * [**Java 中的自定义异常**](//howtodoinjava.com/best-practices/best-practices-for-for-exception-handling/ "Best practices for Exception handling") * [Java 异常文档](https://docs.oracle.com/javase/tutorial/essential/exceptions/runtime.html)