JDK 7使用改进的类型检查捕获多个异常类型和重新抛出异常

时间:2014-10-05 21:08:20

标签: java exception-handling java-7

在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;
    }
  }

根据我的理解,New 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和 SecondException。即使catch子句的异常参数e是类型Exception,也是 编译器可以确定它是FirstException或SecondException的实例。这个 如果将catch参数分配给catch块中的另一个值,则禁用分析。然而, 如果将catch参数分配给另一个值,则必须在其中指定异常类型Exception 方法声明的throws子句。

来自Oracle文档,

详细说明,在Java SE 7及更高版本中,当您在catch子句中声明一个或多个异常类型时, 并重新抛出此catch块处理的异常,编译器验证该类型 rethrown异常符合以下条件:

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点。有人可以用上面提到的代码解释我吗?

1 个答案:

答案 0 :(得分:2)

考虑以下情况:

您的应用程序会抛出其中一个例外FirstExceptionSecondExceptionException

ExceptionFirstExceptionSecondException的超类型,因为它们会延伸Exception

它也应该适用SecondException extends FirstException。因此,FirstExceptionSecondExeptionSecondException的超类型FirstException的子类型。

现在我们有一个总是抛出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.
[...]
} 

你明白了吗?

相关问题