Java异常之catch语句块

来源:互联网 发布:君将哀而生之乎的翻译 编辑:程序博客网 时间:2024/06/05 21:53

今天在阅读项目代码时看到如下奇怪的代码,以为是竖线 | 可以作为多类型赋值,经过网上搜索才知道是Java SE 7新增的功能:一个catch捕获多种类型的异常。原文是Java官方的文档,现翻译如下。红字为个人备注。

public String selectByRule(String ruleId) {try {selectService.select(ruleId, null, false);        return "success";} catch (InstantiationException | IllegalAccessException e) {e.printStackTrace();return "failure";}}


catch块

我们使用一个try语句块以及紧随其后的一个或多个catch语句块来实现异常处理器。注意,在try语句块和第一个catch语句块之间不能有其他代码,示例如下。

try {} catch (ExceptionType name) {} catch (ExceptionType name) {}
每个catch块即是一个异常处理器,catch的参数表明了其所处理的异常的类型。示例中的参数类型ExceptionType,定义了该异常处理器可以处理的异常类型,并且参数类型ExceptionType必须是一个继承自Throwable的类的名字。 异常处理器可以通过name变量读取到所捕捉的异常。

当异常处理器被调用时,对应的catch块内的代码才会执行。那么异常处理器是何时被调用的呢?当某异常处理器的ExceptionType是调用栈上第一个匹配所抛异常的类型时,运行时系统(runtime system)就会调用该异常处理器。只要抛出的对象可以被合法地赋值给异常处理器的参数,运行时系统就会把该异常处理器当作一个匹配。也就是说父类类型如果在前面,可以屏蔽掉后面更精准的子类,如Exception可以匹配所有的异常,这样就是所谓的宽泛异常。

如下的代码片段是writeList方法的两个异常处理器:

try {} catch (IndexOutOfBoundsException e) {    System.err.println("IndexOutOfBoundsException: " + e.getMessage());} catch (IOException e) {    System.err.println("Caught IOException: " + e.getMessage());}

异常处理器可以做的不仅仅是打印错误消息、终止程序。此外,它们还可以进行错误恢复,提示用户做出决定,或者利用异常链把错误传递给更高层级的异常处理器,即如在异常链(Chained Exceptions)章节中所述的。

一个异常处理器如何捕获多种类型的异常

在Java SE 7或者更高版本中,一个catach块可以处理不止一种异常类型。Java的这个功能可以减少重复代码、降低捕获过于宽泛的异常的诱惑。使用方式是,在catch语句中,指明该catch语句块可以处理的异常的类型(们),并使用竖线(|)把各个异常类型隔开,示例如下:
catch (IOException|SQLException ex) {    logger.log(ex);    throw ex;}
注意:如果catch语句块要处理多种异常类型,那么catch的参数隐式地成为不可变(final)变量。在上例中,catch参数ex就是不可变变量,因此在该语句块内你不能赋任何值给它。

原文地址:https://docs.oracle.com/javase/tutorial/essential/exceptions/catch.html

0 0
原创粉丝点击