try-finally 和 try-catch 之间的区别
-
27-09-2019 - |
题
有什么区别
try {
fooBar();
} finally {
barFoo();
}
和
try {
fooBar();
} catch(Throwable throwable) {
barFoo(throwable); // Does something with throwable, logs it, or handles it.
}
我更喜欢第二个版本,因为它让我可以访问 Throwable。这两种变体之间是否存在任何逻辑差异或首选约定?
另外,有没有办法从finally子句中访问异常?
解决方案
这是两个不同的事情:
- 仅当 try 块中抛出异常时,才会执行 catch 块。
- 无论是否抛出异常,finally 块始终在 try(-catch) 块之后执行。
在您的示例中,您尚未显示第三种可能的构造:
try {
// try to execute this statements...
}
catch( SpecificException e ) {
// if a specific exception was thrown, handle it here
}
// ... more catches for specific exceptions can come here
catch( Exception e ) {
// if a more general exception was thrown, handle it here
}
finally {
// here you can clean things up afterwards
}
而且,就像@codeca在他的评论中所说的那样,没有办法访问finally块内的异常,因为即使没有异常,finally块也会被执行。
当然,您可以在块之外声明一个保存异常的变量,并在 catch 块内分配一个值。之后,您可以在finally块中访问该变量。
Throwable throwable = null;
try {
// do some stuff
}
catch( Throwable e ) {
throwable = e;
}
finally {
if( throwable != null ) {
// handle it
}
}
其他提示
这些都不变化,它们是从根本上不同的事情。执行finally
总是,仅catch
在发生异常时。
finally 和 catch 块有很大不同:
- 在 catch 块中,您可以响应抛出的异常。这个街区 仅当存在未处理的异常时才执行 并且该类型与 catch 块参数中指定的类型匹配或者是该类型的子类。
- 最后总会被执行 在 try 和 catch 块之后是否引发异常。
所以
try {
//some code
}
catch (ExceptionA) {
// Only gets executed if ExceptionA
// was thrown in try block
}
catch (ExceptionB) {
// Only executed if ExceptionB was thrown in try
// and not handled by first catch block
}
不同于
try {
//some code
}
finally {
// Gets executed whether or not
// an exception was thrown in try block
}
显著地。
如果你定义了一个 try 块,你必须定义
- 最后一个块,或者
- 一个或多个 catch 块,或者
- 一个或多个 catch 块和一个 finally 块
所以下面的代码也是有效的:
try {
//some code
}
catch (ExceptionA) {
// Only gets executed if
// ExceptionA was thrown in try block
}
catch (ExceptionB) {
// Only executed if ExceptionB was thrown in
// try and not handled by first catch block
}
//even more catch blocks
finally {
// Gets executed whether or not an
// exception was thrown in try block
}
try {
statements;
} catch (exceptionType1 e1) { // one or multiple
statements;
} catch (exceptionType2 e2) {
statements;
}
...
} finally { // one or none
statements;
}
- 所有 try 语句必须包含一个 catch 子句或一个 finally 子句
- 它可以有多个catch子句,但只能有一个finally子句
- 在任何执行过程中,如果发生任何错误,则 Control 将转移到适当的 Catch 块并执行语句,并执行 Final 块。
不管怎样,Finally 块总是被执行,所以一般来说,使用 Final 块,当你有会话、数据库连接或文件或套接字打开时,就会放置关闭这些连接的代码。这只是为了确保应用程序中不会发生内存泄漏或任何其他问题。
最后和catch块有很大的不同:
在catch块,你可以到抛出的异常反应。仅当存在未处理的异常和类型相匹配的一个或是在catch块的参数中指定的一个子类时,执行该块。 最后将try和catch块之后始终执行是否有异常升高或不
尝试用于运行可能抛出异常
的方法捕捉用于“捕获”停止该异常
最后被用于从该异常所需的任何清理被抓住或不
try{
myObject.riskyMethod(); // run a method that may throw an exception
}
catch(Exception ex){
myLogger.log(ex.Message); // "catch" stop that exception
}
finally{
myObject = null; // clean up needed from that exception being caught
}
在我的研究最后块始终执行,它主要是“用于所有打开的连接关闭”,并可以销毁不必要运行的东西。
最后块总是进行。 catch块仅执行时该参数钓到块相匹配的异常。
即使是在第一种形式,你可以在调用的方法记录它。所以,除非你想要做一些特殊的处理权有没有很大的优势。
通常,当我们使用任何资源,如流,连接等。我们必须明确地关闭它们使用finally块。在下面我们从一个文件中使用的FileReader读取数据中给出的程序,我们使用的是最后块关闭它。
import java.io.File;
import java.io.FileReader;
import java.io.IOException;
public class ReadData_Demo {
public static void main(String args[]){
FileReader fr=null;
try{
File file=new File("file.txt");
fr = new FileReader(file); char [] a = new char[50];
fr.read(a); // reads the content to the array
for(char c : a)
System.out.print(c); //prints the characters one by one
}catch(IOException e){
e.printStackTrace();
}
finally{
try{
fr.close();
}catch(IOException ex){
ex.printStackTrace();
}
}
}
}
也许其他球员像我这样的搜索这样的事情。
从当前页 tutpoint
信息Try块将持有这会引发异常的语句。 catch块将举行从try块抛出,并要求消息从catch块产生的参考。 最后块也用于关闭使用资源,如IO收盘,文件关闭,分贝收盘.. 在Java -9增强试穿与资源想出了在资源之外声明的try..in enchanced尝试与资源catch块是必需的。