Java通过示例抑制了异常

顾名思义,抑制的异常是在代码中引发的异常,但是以某种方式被忽略了。如果您还记得 try-catch-finally块的执行顺序以及它们如何返回任何值或异常,那么您会记得,如果同时块中也抛出异常,finally则会抑制在块中抛出的异常try

在Java 7之前,通过记录日志(如果已实现)来通知您这些异常,但是一旦finally块结束,您将无法控制这些异常类型。

好的,借助Java 7中的新功能,您还可以控制这些受抑制的异常。

目录

1.什么是禁止的例外?
2.抑制异常的例子
3.在不同情况下的示范

1.什么是禁止的例外?

在Java 7中,遇到抑制异常的最常见用例是try-with-resources语句。当我们在try块中遇到异常时,应用程序将尝试关闭资源。如果它遇到关闭AutoCloseable资源时可能发生的多个异常,则会将其他异常作为抑制的异常附加到主要异常上

为了支持抑制的异常,在JDK 7中向Throwable类(ExceptionError类的父级)添加了一个新的构造函数和两个新方法。

可投掷。getSupressed(); //返回Throwable []
可投掷。addSupressed(aThrowable);

2.抑制异常的例子

例如,在写入 OutputStream 时,可以从try块中引发异常,并且在尝试关闭 Stream 时,可以从try-with-resources语句中引发最多两个异常。

如果从try块引发异常,并且从try-with-resources语句引发一个或多个异常,则将从try-with-resources语句引发的那些异常抑制,并且由块引发的异常是一个该方法抛出的结果closeStream()

您可以通过从try块引发的异常中调用Throwable.getSuppressed()方法来检索这些受抑制的异常。

3.在不同情况下的示范

例如,我正在编写一个自动关闭的资源(即DirtyResource.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。抑制异常之前功能

package com.how2codex.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中抑制异常之后

package com.how2codex.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块并捕获异常

package com.how2codex.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。默认尝试资源块

package com.how2codex.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)

好了,看到输出包含完整信息以及受抑制的异常,这真是太好了。

 

saigon has written 1445 articles

Leave a Reply