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

为什么顺序在捕获异常时很重要?

晏华奥
2023-03-14

我必须用一些代码来回答这个问题:

假设我编写了以下方法规范:
public void manufacturedata()抛出java。sql。SQLException,java。sql。SQLDataException

您正在为一个将使用此方法的数据库程序编写代码,并且希望专门处理每个程序。try/catch子句应该是什么样的
您可以对catch子句内容使用no-ops——空块{}<我们只对这里语句的语法和结构感兴趣。

我回答说:

try {

} catch(java.sql.SQLException e) {

}
catch(java.sql.SQLDataException e) {

}

出于这个原因,他没有接受这个答案:

“你的catch子句顺序不对。你能解释一下为什么顺序很重要吗?”

他的回答正确吗?

共有3个答案

闻人树
2023-03-14

由于以下原因,在捕获异常时顺序很重要:

记住:

  • 基类变量也可以引用子类对象
  • e是一个参考变量
catch(ExceptionType e){
}

小写字符e是对抛出(并捕获)ExceptionType对象的引用。

为什么你的代码不被接受?

重要的是要记住异常子类必须位于它们的任何超类之前。这是因为使用超类的捕获语句将捕获该类型的异常及其任何子类。因此,如果子类位于其超类之后,则永远不会到达。
此外,在Java中,无法到达的代码是错误的。

SQLExctiveSQLDataExctive的超类

   +----+----+----+
   | SQLException |  `e` can reference SQLException as well as SQLDataException
   +----+----+----+
          ^
          |
          |
+----+----+----+---+
| SQLDataException |   More specific 
+----+----+----+---+

如果你写的代码有错误无法访问的代码(阅读评论):

try{

} 
catch(java.sql.SQLException e){//also catch exception of SQLDataException type 

}
catch(java.sql.SQLDataException e){//hence this remains Unreachable code

}

如果您尝试编译此程序,您将收到一条错误消息,声明第一条捕获语句将处理所有基于SQLExctive的错误,包括SQLDataExctive。这意味着第二条捕获语句将永远不会执行。

正确的html" target="_blank">解决方案?

要修复它,请颠倒捕获语句的顺序。如下所示:

try{

} 
catch(java.sql.SQLDataException e){

}catch(java.sql.SQLException e){

}
司空坚
2023-03-14

在Java中,必须首先放置包含最少的异常。接下来的例外情况必须更具包容性(当它们相关时)。

例如:如果你把最包容的(例外)放在第一位,下一个将永远不会被调用。代码如下:

try {
     System.out.println("Trying to prove a point");
     throw new java.sql.SqlDataException("Where will I show up?");
}catch(Exception e){
     System.out.println("First catch");
} catch(java.sql.SQLException e) {
     System.out.println("Second catch");
}
catch(java.sql.SQLDataException e) {
     System.out.println("Third catch");
}

永远不会打印您期望它打印的消息

锺博耘
2023-03-14

是的,他是对的。正如您在Javadoc中看到的,SQLDataExceptionSQLException的一个子类。因此,您的答案是错误的,因为它会在第二个catch中创建一个无法访问的代码块。

在Java中,这些代码甚至不会编译。在其他语言(例如python)中,这样的代码会产生一个微妙的错误,因为SQLDataException实际上会在第一个块中被捕获,而不是在第二个块中(如果它不是子类的话,情况就是这样)。

如果您回答了catch(java.sql.SQLException | java.sql.SQLDataException e){},它仍然是不正确的,因为这个问题要求专门处理每个异常。

正确答案就在Grijesh的答案里

 类似资料:
  • 问题内容: 如果我没记错的话,应该首先捕获Exception的子类。但是必须捕获任何RuntimeException和一个具体的经过检查的Exception,首先应该捕获它们吗? 这个命令正确吗?还是正确但错误的选择? 问题答案: 顺序是 先匹配的,然后执行 (正如JLS清楚地解释的)。 如果第一个catch匹配到异常,则执行,否则,将尝试下一个,并不断重复直到匹配或不匹配。 因此,在捕获异常时,

  • 问题内容: 在Java中,引发 检查 异常(Exception或其子类型- IOException,InterruptedException等)的方法必须声明 throws 语句: 不声明语句的 方法不能 引发检查的异常。 但是在Java中使用安全方法捕获检查的异常仍然合法: 其实没有 有点可笑:编译器知道 e 不是检查的异常,因此可以将其重新抛出。事情甚至有些荒谬,此代码无法编译: 第一个片段是

  • 问题内容: 我认为Maven依赖关系的顺序之前无关紧要,并认为这是它的一个优点。这是我以前的依赖项: 它运作良好,今天我要把对弹簧的依赖移到最底层,以便与那些球衣相关的东西可以在一起。但是后来我再也无法正常工作了,我的码头抱怨道: 那真的很令人困惑,所以我是否需要考虑依赖顺序?我怎么知道正确的顺序? 问题答案: 依赖关系的顺序确实很重要,因为从2.0.9版开始,Maven如何解决传递依赖关系。文档

  • 问题内容: 最近,我们在Java服务器应用程序中遇到了一个问题,该应用程序正在抛出未捕获的错误,因为Error是Throwable的一个单独的子类,而我们仅捕获了Exceptions。 我们通过捕获Throwables而不是Exceptions解决了眼前的问题,但这使我思考为什么您要捕获Exceptions而不是Throwables,因为您随后会错过Errors。 那么, 当您可以捕获Throwa

  • 我已经用Java编写代码一段时间了。但有时,我不知道什么时候应该抛出异常,什么时候应该捕获异常。我正在做一个有很多方法的项目。层次结构是这样的- 所以目前我正在做的是-我在所有方法中抛出异常并在方法A中捕获它,然后将其记录为错误。 但我不确定这是否是正确的方法?或者我应该开始在所有方法中捕获异常。这就是为什么这种混乱始于我的 - 我什么时候应该抓住异常与何时应该抛出异常。我知道这是一个愚蠢的问题,

  • 问题内容: 最近,我一直在设计响应速度更快的网站,并且经常使用CSS媒体查询。我注意到的一种模式实际上是定义媒体查询的顺序。我没有在每个浏览器中都进行过测试,只是在Chrome上进行了测试。有这种行为的解释吗?有时,当您的网站无法正常运行时,它会令人沮丧,并且您不确定这是查询还是编写查询的顺序。 这是一个例子: HTML CSS: 但是,如果我最后一次为1024x600编写查询,浏览器将忽略它,并