【问题标题】:JDK 7 Catching Multiple Exception Types and Rethrowing Exceptions with Improved Type CheckingJDK 7 通过改进的类型检查捕获多种异常类型并重新抛出异常
【发布时间】:2014-11-30 04:22:17
【问题描述】:

在 Java 7 之前,如果我们必须从方法中重新抛出异常,那么我们将不得不采用两种方法中的任何一种,

public void rethrowException(String exceptionName) throws FirstException, SecondException{
    try {
      if (exceptionName.equals("First")) {
        throw new FirstException();
      } else {
        throw new SecondException();
      }
    } catch (FirstExceptione) {
      throw e;
    }catch (SecondException) {
      throw e;
    }
  }

第二个是,

public void rethrowException(String exceptionName) throws Exception {
    try {
      if (exceptionName.equals("First")) {
        throw new FirstException();
      } else {
        throw new SecondException();
      }
    } catch (Exception e) {
      throw e;
    }
  }

根据我的理解,新 Java 7.0 已经改进了,您可以捕获广泛的异常,并且仍然在方法定义中保留狭窄的异常,就像下面的代码一样,

public void rethrowException(String exceptionName)
  throws FirstException, SecondException {
    try {
      // ...
    }
    catch (Exception e) {
      throw e;
    }
  }

Java SE 7 编译器可以确定语句 throw e 抛出的异常必须有 来自 try 块,try 块抛出的唯一异常可以是 FirstException 和 第二异常。即使 catch 子句的异常参数 e 是 Exception 类型, 编译器可以确定它是 FirstException 还是 SecondException 的实例。这 如果将 catch 参数分配给 catch 块中的另一个值,则禁用分析。然而, 如果catch参数被赋值给另一个值,则必须在中指定异常类型Exception 方法声明的 throws 子句。

来自 Oracle 文档,

具体来说,在 Java SE 7 及更高版本中,当您在 catch 子句中声明一种或多种异常类型时, 并重新抛出此 catch 块处理的异常,编译器会验证 重新抛出的异常满足以下条件:

1) The try block is able to throw it.
2) There are no other preceding catch blocks that can handle it.
3) It is a subtype or supertype of one of the catch clause's exception parameters.
4) In releases prior to Java SE 7, you cannot throw an exception that is a supertype of one of   
the catch clause's exception parameters. A compiler from a release prior to Java SE 7 generates 
the error, "unreported exception Exception; must be caught or declared to be thrown" at the 
statement throw e. The compiler checks if the type of the exception thrown is assignable to any 
of the types declared in the throws clause of the rethrowException method declaration. However, 
the type of the catch parameter e is Exception, which is a supertype, not a subtype, of 
FirstException andSecondException.

我未能从理论上理解第 3 点和第 4 点。有人可以用上面提到的代码来解释我吗?

【问题讨论】:

    标签: java exception-handling java-7


    【解决方案1】:

    考虑以下情况:

    您的应用程序引发FirstExceptionSecondExceptionException 的异常之一

    ExceptionFirstExceptionSecondException 的超类型,因为它们扩展了Exception

    它也应该适用于SecondException extends FirstException。所以FirstExceptionSecondExeption 的超类型,SecondExceptionFirstException 的子类型。

    现在我们有了一个总是抛出SecondException的方法。

    第一种情况:

    try {
    [...]
    } catch(SecondException se) {
    // Exception gets always caught in here
    [...]
    } catch(FirstException fe) {
    [...]
    } catch(Exception e) {
    [...]
    }
    

    第二种情况:

    try {
    [...]
    } catch(Exception e) {
    // Exception gets always caught in here
    // because Exception is supertype of all other Exception
    [...]
    } catch(FirstException fe) {
    [...]
    } catch(SecondException se) {
    // is never called.
    [...]
    } 
    

    你明白了吗?

    【讨论】:

    • 我知道这一点。根据我的说法,第二种情况将是编译时错误,因为异常总是会被第一个 catch(Exception e){ //....} 捕获
    • 异常被称为从非常特殊到一般。因此,如果您捕获非常普遍的异常“Exception”,那么“SecondException”和“FirstException”将包含在该异常案例中。所以后面的异常块就不会进入了。
    猜你喜欢
    • 1970-01-01
    • 2012-07-25
    • 2016-11-13
    • 1970-01-01
    • 2010-10-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多