重新抛出异常:为什么方法在没有throws子句的情况下编译? [英] Rethrowing an Exception: Why does the method compile without a throws clause?

查看:144
本文介绍了重新抛出异常:为什么方法在没有throws子句的情况下编译?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在下面的源代码中我重新抛出一个异常

为什么没有必要把抛出方法签名上的关键字?

On the source code below I'm rethrowing an Exception.
Why is it not necessary to put the throws keyword on the method's signature?

public void throwsOrNotThrowsThatsTheQuestion() {
    try {

        // Any processing

    } catch (Exception e) {
        throw e;
    }
}


推荐答案

这行为似乎只发生在Java 1.7上。使用1.6编译时,我收到以下编译器错误消息:

This behavior appears to occur only on Java 1.7. When compiling with 1.6, I get the following compiler error message:

c:\dev\src\misc>javac -source 1.6 Main.java
warning: [options] bootstrap class path not set in conjunction with -source 1.6
Main.java:22: error: unreported exception Exception; must be caught or declared
to be thrown
        throw e;
        ^
1 error
1 warning

但是使用Java 1.7 ,它编译。<​​/ p>

But with Java 1.7, it compiles.

c:\dev\src\misc>javac -source 1.7 Main.java

c:\dev\src\misc>

...直到我实际抛出异常尝试块:

... Until I actually throw an Exception in the try block:

public static void throwsOrNotThrowsThatsTheQuestion() {
try {

    // Any processing
    throw new IOException("Fake!");

} catch (Exception e) {
    throw e;
}

编译......

c:\dev\src\misc>javac -source 1.7 Main.java
Main.java:22: error: unreported exception IOException; must be caught or declare
d to be thrown
        throw e;
        ^
1 error

看起来Java 1.7已经足够智能检测可能通过分析 try 块代码抛出的 Exception (s)的类型,其中1.6只是看到抛出e; 类型异常并仅为此发出错误。

It looks like Java 1.7 got smart enough to detect the kind of Exception(s) that might be thrown by analyzing the try block code, where as 1.6 just saw throw e; of type Exception and gave an error just for that.

更改它以抛出 RuntimeException 使其按预期编译,因为一如既往,未经检查异常 s don不需要抛出子句:

Changing it to throw a RuntimeException made it compile as expected, because as always, unchecked Exceptions don't need a throws clause:

public static void throwsOrNotThrowsThatsTheQuestion() {
try {

    // Any processing
    throw new RuntimeException("Fake!");

} catch (Exception e) {
    throw e;
}

编译......

c:\dev\src\misc>javac -source 1.7 Main.java

c:\dev\src\misc>

解释

以下是发生的事情:

Java 7引入了更具包容性的类型检查。引用...

Java 7 introduced more inclusive type checking. Quoting...


请考虑以下示例:

Consider the following example:



static class FirstException extends Exception { }
static class SecondException extends Exception { }

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




此示例的try块可以抛出FirstException或SecondException。假设您要在rethrowException方法声明的throws子句中指定这些异常类型。在Java SE 7之前的版本中,您不能这样做。因为catch子句的异常参数e是类型Exception,并且catch块重新抛出异常参数e,所以只能在rethrowException方法声明的throws子句中指定异常类型Exception。

This examples's try block could throw either FirstException or SecondException. Suppose you want to specify these exception types in the throws clause of the rethrowException method declaration. In releases prior to Java SE 7, you cannot do so. Because the exception parameter of the catch clause, e, is type Exception, and the catch block rethrows the exception parameter e, you can only specify the exception type Exception in the throws clause of the rethrowException method declaration.

但是,在Java SE 7中,可以在rethrowException方法声明的throws子句中指定异常类型FirstException和SecondException。 Java SE 7编译器可以确定语句throw e抛出的异常必须来自try块,并且try块抛出的唯一异常可以是FirstException和SecondException。即使catch子句的异常参数e是类型Exception,编译器也可以确定它是FirstException或SecondException的实例:

However, in Java SE 7, you can specify the exception types FirstException and SecondException in the throws clause in the rethrowException method declaration. The Java SE 7 compiler can determine that the exception thrown by the statement throw e must have come from the try block, and the only exceptions thrown by the try block can be FirstException and SecondException. Even though the exception parameter of the catch clause, e, is type Exception, the compiler can determine that it is an instance of either FirstException or SecondException:

(强调我的)

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

这篇关于重新抛出异常:为什么方法在没有throws子句的情况下编译?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆