在 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) 如果你想要 Type1
和 Type2
的不同行为,那么你不能使用这个构造。
我想的也差不多。只是想我会要求确定
@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 )
IndexOutOfBoundException
和(非 RuntimeException
)Throwable
相同但想处理(非 IndexOutOfBoundsException
) RuntimeException
不同,那么新的 Java 7 语法就没用了。以上是关于在 Java 中是不是可以在同一个 catch 块中捕获两个异常? [复制]的主要内容,如果未能解决你的问题,请参考以下文章