2014-10-05 34 views
3

到Java 7之前的异常,如果我们不得不从一个方法重新抛出一个异常,那么我们将不得不做任何的2种方式,JDK 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中的编译器可以判断为通过声明扔é抛出的异常必须有来自try块 ,并通过try块抛出的唯一的例外可能是FirstException和 SecondException。即使catch子句的异常参数e是Exception类型,编译器也可以确定它是FirstException或SecondException的实例。如果将catch参数分配给catch块中的另一个值,则此分析将被禁用。但是,如果将catch参数分配给另一个值,则必须在方法声明的throws子句中指定异常类型Exception( )。

从甲骨文的文档,

具体而言,在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. 

我没有undertand第三和4rth点theoritically。有人可以用上面提到的代码来解释我吗?

回答

2

考虑以下情况:

您的应用程序抛出的异常FirstExceptionSecondException之一,Exception

ExceptionFirstException超类型,SecondException因为他们延长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. 
[...] 
} 

你看到了吧?

+0

我知道这一点。第二种情况是编译时错误,因为异常总是会被第一个catch捕获(Exception e){// ....} – 2014-10-05 21:46:00

+0

异常从非常特殊的状态调用到一般状态。因此,如果您捕获非常普遍的异常“Exception”,那么在该异常情况下包含“SecondException”和“FirstException”。所以之后的异常块将不会被输入。 – sxleixer 2014-11-20 08:44:46