“啊,你来了,我一直在找你呢。”

“发生了什么事吗?”

“没有,但我们还在学习。”

“好的。我在听。”

“我想告诉你更多关于异常的事情:”

“在 Java 7 中,try-catch结构通过添加多个 catch块得到了轻微扩展。看这个例子:”

Java 5
try
{
  …
}
 catch (IOException ex)
{
 logger.log(ex);
 throw ex;
}
 catch (SQLException ex)
{
 logger.log(ex);
 throw ex;
}
Java 7
try
{
  …
}
 catch (IOException | SQLException ex)
{
 logger.log(ex);
 throw ex;
}

“那么现在我们可以编写由 OR 运算符分隔的多个异常('|' 是二进制 OR)吗?”

“对啊,这样不是很方便吗?”

“嗯。但是 catch 块中的异常对象的类型是什么?”

“毕竟,IOException 有它的方法,SQLException 也有它的方法。”

“异常类型将是它们共同祖先类的异常类型。”

“啊。也就是说,它很可能是ExeptionRuntimeException。那为什么不直接写catch(Exception e)呢?”

“有时单独处理错误时,将它们分组很方便,将一些错误写入日志,重新抛出其他错误,并以其他方式处理其他错误。”

“换句话说,这个方案被认为解决了处理不同错误的重复 catch 块的问题。”

“啊。我明白了。谢谢,艾莉。”

“这还不是全部。我想告诉你更多有关finally块的信息。”

“你可能已经知道,这个块总是被执行。”

“当我说总是时,我的意思是绝对总是。”

“例如:”

最后使用示例
try
{
 return 1;
}
 finally
{
 return 0;
}

“这里在try块中有一个return,在finally块中有一个return。所以这个方法的返回值将是数字 0。”

“无论发生什么,finally块都会执行。它的return语句会用它自己的值覆盖其他返回值。”

“我懂了。”

“但是,方法可以返回值或抛出异常。

“所以,如果在 try 块中返回了一个值,但finally块抛出异常,那么结果将是异常

“如果在try块中抛出异常但finally块有 return 语句怎么办?”

“然后就好像这个方法正常工作了,并且返回了return语句中的值。

例子 结果
try
{
 return 1;
}
 finally
{
 return 0;
}
0
try
{
 return 1;
}
 finally
{
 throw new RuntimeException();
}
运行时异常
try
{
 throw new RuntimeException();
}
 finally
{
 return 0;
}
0
try
{
 throw new RuntimeException();
}
 finally
{
 throw new IOException();
}
异常

“可能无法执行 finally 方法的唯一原因是程序通过调用 System.exit ();方法立即终止。”

例子
try
{
 System.exit(0);
 return 1;
}
 finally
{
 return 0;
}

“我懂了。”

“请记住,所有这些话题通常都会在面试中被问到,所以你最好理解并记住它们。”