🔥码云GVP开源项目 12k star Uniapp+ElementUI 功能强大 支持多语言、二开方便! 广告
# Java 抑制异常示例 > 原文: [https://howtodoinjava.com/java7/java-suppressed-exceptions/](https://howtodoinjava.com/java7/java-suppressed-exceptions/) 顾名思义, [**被抑制的异常**](https://docs.oracle.com/javase/tutorial/essential/exceptions/tryResourceClose.html#suppressed-exceptions "suppressed-exceptions")是在代码中引发的异常,但是以某种方式被忽略了。 如果您记得[`try-catch-finally`](https://howtodoinjava.com/java7/automatic-resource-management-with-try-with-resources-in-java-7/)块的执行顺序以及它们如何返回任何值或异常,那么您会记得,如果`try`中引发了异常,则也将抑制`finally`块中引发的**异常**。 在 Java 7 之前的版本中,您通过记录日志了解了这些异常(如果已实现),但是一旦`finally`块结束,您就无法控制这些类型的异常。 好吧,借助 Java 7 中的[**新特性**](https://howtodoinjava.com/java7/java-7-changes-features-and-enhancements/ "java 7 features"),您还可以控制这些受抑制的异常。 ```java Table of contents 1\. What are suppressed exceptions? 2\. Suppressed exception example 3\. Demonstration in different scenarios ``` ## 1\. 什么是禁止的异常? 在 Java 7 中,遇到抑制异常的最常见用例是 **try-with-resources** 语句。 当我们在`try`块中遇到异常时,应用程序将尝试关闭资源。 如果它遇到关闭`AutoCloseable`资源时可能发生的多个异常,则会将其他异常作为**抑制的异常**附加到主要异常上。 为了支持抑制的异常,在 JDK 7 中向[`Throwable`](https://docs.oracle.com/javase/7/docs/api/java/lang/Throwable.html "Throwable")类(`Exception`和`Error`类的父级)添加了新的构造器和两个新方法。 ```java Throwable.getSupressed(); // Returns Throwable[] Throwable.addSupressed(aThrowable); ``` ## 2\. 抑制异常的例子 例如,在写入输出流时,可以从`try`块引发一个异常,当`try-with-resources`语句尝试关闭流时,可以从该异常中引发最多两个异常。 如果从`try`块引发一个异常,并且从`try-with-resources`语句引发一个或多个异常,则将从`try-with-resources`语句引发的那些异常抑制,并且由该块引发的异常由`closeStream()`方法抛出。 您可以通过从`try`块引发的异常中调用`Throwable.getSuppressed()`方法来检索这些受抑制的异常。 ## 3\. 在不同情况下的示例 例如,我正在编写一个自动关闭的资源(即`DirtyResource.java`),无论我们尝试访问它还是关闭它,它都会引发异常。 这样,当以不同方式访问时,我们将能够看到不同的行为。 ```java public class DirtyResource implements AutoCloseable { /** * Need to call this method if you want to access this resource * @throws RuntimeException no matter how you call this method * */ public void accessResource() { throw new RuntimeException("I wanted to access this resource. Bad luck. Its dirty resource !!!"); } /** * The overridden closure method from AutoCloseable interface * @throws Exception which is thrown during closure of this dirty resource * */ @Override public void close() throws Exception { throw new NullPointerException("Remember me. I am your worst nightmare !! I am Null pointer exception !!"); } } ``` #### 3.1 抑制异常之前的特性 ```java package com.howtodoinjava.demo.core; import static java.lang.System.err; public class SuppressedExceptionDemoWithTryFinallyPrevious { /** * Executable member function demonstrating suppressed exceptions * One exception is lost if not added in suppressed exceptions list */ public static void memberFunction() throws Exception { DirtyResource resource= new DirtyResource(); try { resource.accessResource(); } finally { resource.close(); } } public static void main(String[] arguments) throws Exception { try { memberFunction(); } catch(Exception ex) { err.println("Exception encountered: " + ex.toString()); final Throwable[] suppressedExceptions = ex.getSuppressed(); final int numSuppressed = suppressedExceptions.length; if (numSuppressed > 0) { err.println("tThere are " + numSuppressed + " suppressed exceptions:"); for (final Throwable exception : suppressedExceptions) { err.println("tt" + exception.toString()); } } } } } Output: Exception encountered: java.lang.NullPointerException: Remember me. I am your worst nightmare !! I am Null pointer exception !! ``` 如您所见,仅捕获了一个异常,而第二个`RuntimeException`被抑制。 #### 3.2 在 Java 7 中抑制异常之后 ```java package com.howtodoinjava.demo.core; import static java.lang.System.err; public class SuppressedExceptionDemoWithTryFinallyNew { /** * Executable member function demonstrating suppressed exceptions * Suppressed expression is added back in primary exception */ public static void memberFunction() throws Exception { Throwable th = null; DirtyResource resource= new DirtyResource(); try { resource.accessResource(); } catch(Exception e) { th = e; } finally { try { resource.close(); } catch(Exception e) { if(th != null) { e.addSuppressed(th); //Add to primary exception throw e; } } } } /** * Executable function demonstrating suppressed exceptions. */ public static void main(String[] arguments) throws Exception { try { memberFunction(); } catch(Exception ex) { err.println("Exception encountered: " + ex.toString()); final Throwable[] suppressedExceptions = ex.getSuppressed(); final int numSuppressed = suppressedExceptions.length; if (numSuppressed > 0) { err.println("tThere are " + numSuppressed + " suppressed exceptions:"); for (final Throwable exception : suppressedExceptions) { err.println("tt" + exception.toString()); } } } } } Output: Exception encountered: java.lang.NullPointerException: Remember me. I am your worst nightmare !! I am Null pointer exception !! There are 1 suppressed exceptions: java.lang.RuntimeException: I wanted to access this resource. Bad luck. Its dirty resource !!! ``` 在这里,在`catch`块中,我们可以访问两个异常。 一个作为主要异常,第二个作为受抑制异常。 #### 3.3 成员函数中的`try-with-resource`块并捕获异常 ```java package com.howtodoinjava.demo.core; import static java.lang.System.err; public class SuppressedExceptionDemoWithTryCatch { public static void memberFunction() throws Exception { try (DirtyResource resource= new DirtyResource()) { resource.accessResource(); } } /** * Executable member function demonstrating suppressed exceptions using try-with-resources */ public static void main(String[] arguments) throws Exception { try { memberFunction(); } catch(Exception ex) { err.println("Exception encountered: " + ex.toString()); final Throwable[] suppressedExceptions = ex.getSuppressed(); final int numSuppressed = suppressedExceptions.length; if (numSuppressed > 0) { err.println("tThere are " + numSuppressed + " suppressed exceptions:"); for (final Throwable exception : suppressedExceptions) { err.println("tt" + exception.toString()); } } } } } Output: Exception encountered: java.lang.RuntimeException: I wanted to access this resource. Bad luck. Its dirty resource !!! There are 1 suppressed exceptions: java.lang.NullPointerException: Remember me. I am your worst nightmare !! I am Null pointer exception !! ``` 太好了! 在成员函数中使用`try-with-resource`时,我们能够看到这两种异常。 #### 3.4 默认`try-with-resource`块 ```java package com.howtodoinjava.demo.core; public class SuppressedExceptionDemoWithTryWithResource { /** * Demonstrating suppressed exceptions using try-with-resources */ public static void main(String[] arguments) throws Exception { try (DirtyResource resource= new DirtyResource()) { resource.accessResource(); } } } Output: Exception in thread "main" java.lang.RuntimeException: I wanted to access this resource. Bad luck. Its dirty resource !!! at DirtyResource.accessResource(DirtyResource.java:9) at SuppressedExceptionDemoWithTryWithResource.main(SuppressedExceptionDemoWithTryWithResource.java:12) Suppressed: java.lang.NullPointerException: Remember me. I am your worst nightmare !! I am Null pointer exception !! at DirtyResource.close(DirtyResource.java:19) at SuppressedExceptionDemoWithTryWithResource.main(SuppressedExceptionDemoWithTryWithResource.java:13) ``` 好吧,非常高兴看到包含**抑制异常**的完整信息的输出。 学习愉快!