当前位置: 首页 > 知识库问答 >
问题:

JDK 7通过改进的类型检查捕获多个异常类型并重新引发异常

韩禄
2023-03-14

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

根据我的理解,新Java7.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参数被分配给另一个值,则必须在方法声明的throws子句中指定异常类型exception。

从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.

我没有从理论上理解第三点和第四点。有人能用上面提到的代码来解释我吗?

共有1个答案

纪秋月
2023-03-14

考虑以下情况:

应用程序抛出一个异常,即第一个异常、第二个异常、异常

异常是第一异常、第二异常的超类型,因为它们扩展了异常。

它还应该适用于秒异常扩展FirstException。因此FirstException秒异常的超类型,而秒异常FirstException的子类型。

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

第一种情况:

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.
[...]
} 

你明白重点了吗?

 类似资料:
  • 问题内容: e是Exception类型,但在以下代码中显示Exception1: 根据我的研究,“ e”应为Exception类型,它是Exception1和Exception2的通用基类。从第1行的消息可以明显看出这一点。 但是为什么: ?谢谢。 问题答案: 当您使用 多catch子句 (的形式),在编译时类型是最大的类型两种类型的共同点,因为课程的代码必须处理两种类型exception.Fro

  • 我有以下两个示例,我不清楚java.lang.Exception是如何处理的:作为检查的或未检查的异常。 以下方法编译成功: 在这里,我认为java.lang.Exception是威胁java.lang.RuntimeException或java.lang.Error。不处理也可以声明扔。 如果我们没有使用异常,而是使用了检查异常(它是java.lang.Exception的子类),那么您必须在方

  • 问题内容: 我想一个更清洁的方式来获得以下功能,以捕捉和在一个块: 有什么办法吗?还是我必须分开抓住它们? 并具有一个共享的基类,但它们也与其他我要介绍的类型共享它,因此我不能只抓住基类。 问题答案: 更新: 从PHP 7.1开始,此功能可用。 语法为: 文件:https://www.php.net/manual/en/language.exceptions.php#example-287 RFC

  • 找不到指定的模型:User\u model Filename:/opt/lampp/htdocs/ci/system/core/Loader。php 电话号码:348 回溯: 文件:/opt/lampp/htdocs/ci/index。php行:315函数:需要一次 我试图改变名称,但它不工作......这个代码模型

  • 我有以下情况: 所有代码都在@Transactional内部(传播=传播。REQUIRES_NEW)。基本上,我想调用< code>doSomething,如果它抛出一个异常,设置实体的一个字段,提交,然后再抛出异常。但是,它不起作用,因为事务被标记为回滚。

  • 我正在java中做一个火花流项目。我试图发送一些消息从火花到阿帕奇Kafka使用Kafka-生产者java api。由于为每个元素创建KafkaProducer实例将非常昂贵,所以我试图使用一个使用apache公共池框架的生产者池。如下面的代码片段所示,我正在创建GenericObjectpool实例,并将其广播如下所示:- KafkaProducerFactory类的代码粘贴在下面:- 但上面的