在 Java 中是不是可以在同一个 catch 块中捕获两个异常? [复制]

Posted

技术标签:

【中文标题】在 Java 中是不是可以在同一个 catch 块中捕获两个异常? [复制]【英文标题】:Is it possible in Java to catch two exceptions in the same catch block? [duplicate]在 Java 中是否可以在同一个 catch 块中捕获两个异常? [复制] 【发布时间】:2012-06-28 00:06:06 【问题描述】:

我需要捕获两个异常,因为它们需要相同的处理逻辑。我想做类似的事情:

catch (Exception e, ExtendsRuntimeException re) 
    // common logic to handle both exceptions

是否可以避免在每个 catch 块中重复处理程序代码?

【问题讨论】:

查看docs.oracle.com/javase/7/docs/technotes/guides/language/… 了解更多 Java 7 增强功能。我对这个问题有点惊讶,它的答案获得了如此多的赞成票。 【参考方案1】:

Java 7 及更高版本

支持Multiple-exception catches,从 Java 7 开始。

语法是:

try 
     // stuff
 catch (Exception1 | Exception2 ex) 
     // Handle both exceptions

ex 的静态类型是列出的异常中最专业的常见超类型。有一个很好的特性,如果你在 catch 中重新抛出 ex,编译器就会知道只能抛出一个列出的异常。


Java 6 及更早版本

在 Java 7 之前,有一些方法可以处理这个问题,但它们往往不够优雅,并且有局限性。

方法#1

try 
     // stuff
 catch (Exception1 ex) 
     handleException(ex);
 catch (Exception2 ex) 
     handleException(ex);


public void handleException(SuperException ex) 
     // handle exception here

如果异常处理程序需要访问在try 之前声明的局部变量,这会变得很混乱。如果处理程序方法需要重新抛出异常(并且已检查),那么您会遇到签名的严重问题。具体来说,handleException 必须声明为 throwing SuperException ...这可能意味着您必须更改封闭方法的签名,等等。

方法#2

try 
     // stuff
 catch (SuperException ex) 
     if (ex instanceof Exception1 || ex instanceof Exception2) 
         // handle exception
      else 
         throw ex;
     

再一次,我们遇到了签名的潜在问题。

方法#3

try 
     // stuff
 catch (SuperException ex) 
     if (ex instanceof Exception1 || ex instanceof Exception2) 
         // handle exception
     

如果您省略 else 部分(例如,因为目前没有 SuperException 的其他子类型),代码会变得更加脆弱。如果异常层次结构被重新组织,这个没有else 的处理程序最终可能会默默地吃掉异常!

【讨论】:

如果是这种情况,生成的 catch 块将如何处理特定类型异常所特有的函数?例如 ex.functionFromExceptionType2()ex.functionFromExceptionType1() @Peaches491 (1) 绝大多数异常都有完全相同的方法集; (2) 如果你想要 Type1Type2 的不同行为,那么你不能使用这个构造。 我想的也差不多。只是想我会要求确定 @emory 我可能错了,但例外是对象。那么您不能使用instanceof 函数来查看您的异常对象在catch 语句中是一种类型还是另一种类型?因此,您可以捕获、执行通用代码,然后使用带有 instanceof 的 if 块来执行不同的代码。 @Sephallia 没错。它似乎倒退了,但你可以在 catch 语句中使用强制转换。【参考方案2】:

在 Java SE 7 发布之前,我们习惯于编写带有多个与 try 块相关联的 catch 语句的代码。 一个非常基本的例子:

 try 
  // some instructions
 catch(ATypeException e) 
 catch(BTypeException e) 
 catch(CTypeException e) 

但是现在随着 Java 的最新更新,我们可以在单个 catch 子句中处理多个异常,而不是编写多个 catch 语句。这是一个展示如何实现此功能的示例。

try 
// some instructions
 catch(ATypeException|BTypeException|CTypeException ex) 
   throw e;

因此单个catch子句中的多个异常不仅可以简化代码,还可以减少代码的冗余。 我发现这篇文章很好地解释了这个特性及其实现。 Improved and Better Exception Handling from Java 7 这也可能对您有所帮助。

【讨论】:

您的回答晚了 18 个月,没有添加任何新内容。在这种情况下,最好简单地对包含您认为有用的信息的答案进行投票。【参考方案3】:

http://docs.oracle.com/javase/tutorial/essential/exceptions/catch.html 涵盖在同一块中捕获多个异常。

 try 
     // your code
 catch (Exception1 | Exception2 ex) 
     // Handle 2 exceptions in Java 7

我正在制作学习卡,这个帖子很有帮助,只是想投入我的两分钱。

【讨论】:

您的回答晚了 6 个月,并且没有添加任何新内容。在这种情况下,最好简单地对包含您认为有用的信息的答案进行投票。【参考方案4】:

Java

try 

 catch (ExceptionType name) 

 catch (ExceptionType name) 


文档:

每个 catch 块都是一个异常处理程序,并处理 由其参数指示的异常。参数类型,ExceptionType, 声明处理程序可以处理的异常类型,并且必须是 从 Throwable 类继承的类的名称。

对于 Java 7,您可以在一个 catch 块上捕获多个异常:

catch (IOException|SQLException ex) 
    logger.log(ex);
    throw ex;

文档:

在 Java SE 7 及更高版本中,单个 catch 块可以处理多个 异常类型。此功能可以减少代码重复并减少 捕捉过于宽泛的异常的诱惑。

参考: http://docs.oracle.com/javase/tutorial/essential/exceptions/catch.html

【讨论】:

【参考方案5】:

对于 Java

try 
    // common logic to handle both exceptions
 catch (Exception ex) 
    if (ex instanceof Exception1 || ex instanceof Exception2) 

    
    else 
        throw ex;
        // or if you don't want to have to declare Exception use
        // throw new RuntimeException(ex);
    

编辑并用异常替换 Throwable。

【讨论】:

我认为这比杰夫的回答更具可读性 您应该避免捕获过于广泛的异常,这正是 Java 7 更改的动力。此外,你永远不应该抓住你无法处理的事情。最后,你永远不应该捕获错误,因此你也不应该捕获更广泛的 Throwable。【参考方案6】:

如果您不在 java 7 上,您可以将异常处理提取到一个方法中 - 这样您至少可以最大限度地减少重复

try 
   // try something

catch(ExtendsRuntimeException e)  handleError(e); 
catch(Exception e)  handleError(e); 

【讨论】:

好答案+1。 示例代码没有意义。如果你的命名约定很好,那么ExtendsRuntimeException 就是Exception。所以不需要第一个 catch 块。更好的示例是 catch(RuntimeExceptionA e ) handleAB( e ) ; catch (RuntimeExceptionB e) handleAB (e); catch (RuntimeExceptionC e) handleC (e); ` 无法将它们全部折叠成catch ( RuntimeException e ) 即使使用 java 7,这种方法也可能是必要的。例如,如果您想处理 IndexOutOfBoundException 和(非 RuntimeExceptionThrowable 相同但想处理(非 IndexOutOfBoundsException ) RuntimeException 不同,那么新的 Java 7 语法就没用了。

以上是关于在 Java 中是不是可以在同一个 catch 块中捕获两个异常? [复制]的主要内容,如果未能解决你的问题,请参考以下文章

java中 在一个异常处理中啥语句块是可多个的

Java中trycatchfinally执行顺序

java中try-catch模块中with语句块的作用

Java——异常

请简述JAVA中 try-catch-finally 语句的执行过程 简单明了 好的话 加分(曹苇提问)

在 Java 中是不是可以在同一个 catch 块中捕获两个异常? [复制]