Java try catch 最后似乎毫无意义
Java try catch finally seems pointless
这是一个很愚蠢的问题,但我不明白 catch 和 finally 的结合使用。据我所知,无论是否会引发异常,都会执行 catch 块之后的代码,所以为什么要使用
try
{
doSomething();
}
catch(Exception e)
{
e.printStackTrace();
}
finally
{
doSomethingInFinally();
}
而不是
try
{
doSomething();
}
catch(Exception e)
{
e.printStackTrace();
}
doSomethingInFinally();
?我总是看到人们使用第一种模式,但我认为这是额外的代码。
因为您将在 try {}
语句中途停止执行。在您的 finally
中,您可能担心关闭文件句柄、套接字等
我们几乎从不捕捉(或应该捕捉)Exception
。我们将捕获 Exception
的子类。在那种情况下,如果 doSomething()
抛出 catch 子句未处理的异常,则 doSomethingInFinally()
将不会在第二个示例中执行。
有些情况下您的建议不起作用
根本没有catch语句(抛出异常时方法不会继续执行)
catch块重新抛出异常
- try 块中有 return 语句。
- catch 语句不处理超类型异常(如您的情况下的
Throwable
)。
我能给你的最好解释是将你引导至 java doc
来自 Java 文档:
This ensures that the finally block is executed even if an unexpected
exception occurs.
还有一个跟进
Putting cleanup code in a finally block is always a good practice,
even when no exceptions are anticipated.
这是一个简单的场景,为什么 finally 很重要:
LeakableIO i;
try{
i = new LeakableIO();
// do more
}catch(MyException e){
return null;
}
i.close()
我们假设有一个错误所以return
被执行了,你认为i.close()
会不会在return之后被调用?答案是否定的。
不同之处在于,一种形式可能会错过最后的内容。
doSomethingAfter
将 几乎总是 被调用。唯一不会被调用的情况是 doSomethingWithException
抛出异常。
public void test1() {
try {
doSomething();
} catch (Exception e) {
doSomethingWithException();
}
doSomethingAfter();
}
doSomethingAfter
将 总是 被调用,无论发生什么。
public void test2() {
try {
doSomething();
} catch (Exception e) {
doSomethingWithException();
} finally {
doSomethingAfter();
}
}
一个return
也挡不住。同样 doSomethingAfter
将 总是 被调用。
public void test3() {
try {
doSomething();
} catch (Exception e) {
doSomethingWithException();
return;
} finally {
doSomethingAfter();
}
}
public int method1()
{
try
{
return 1;
doSomething();
}
catch(Exception e)
{
return 0;
e.printStackTrace();
}
finally
{
System.out.println("Hello user");
}
}
在上述方法中,Hello user 将始终被打印出来。因为存在于 finally 块中的代码将始终执行。
基本上在 JDBC 中,finally 块用于关闭连接。
这是一个很愚蠢的问题,但我不明白 catch 和 finally 的结合使用。据我所知,无论是否会引发异常,都会执行 catch 块之后的代码,所以为什么要使用
try
{
doSomething();
}
catch(Exception e)
{
e.printStackTrace();
}
finally
{
doSomethingInFinally();
}
而不是
try
{
doSomething();
}
catch(Exception e)
{
e.printStackTrace();
}
doSomethingInFinally();
?我总是看到人们使用第一种模式,但我认为这是额外的代码。
因为您将在 try {}
语句中途停止执行。在您的 finally
中,您可能担心关闭文件句柄、套接字等
我们几乎从不捕捉(或应该捕捉)Exception
。我们将捕获 Exception
的子类。在那种情况下,如果 doSomething()
抛出 catch 子句未处理的异常,则 doSomethingInFinally()
将不会在第二个示例中执行。
有些情况下您的建议不起作用
根本没有catch语句(抛出异常时方法不会继续执行)
catch块重新抛出异常
- try 块中有 return 语句。
- catch 语句不处理超类型异常(如您的情况下的
Throwable
)。
我能给你的最好解释是将你引导至 java doc
来自 Java 文档:
This ensures that the finally block is executed even if an unexpected exception occurs.
还有一个跟进
Putting cleanup code in a finally block is always a good practice, even when no exceptions are anticipated.
这是一个简单的场景,为什么 finally 很重要:
LeakableIO i;
try{
i = new LeakableIO();
// do more
}catch(MyException e){
return null;
}
i.close()
我们假设有一个错误所以return
被执行了,你认为i.close()
会不会在return之后被调用?答案是否定的。
不同之处在于,一种形式可能会错过最后的内容。
doSomethingAfter
将 几乎总是 被调用。唯一不会被调用的情况是 doSomethingWithException
抛出异常。
public void test1() {
try {
doSomething();
} catch (Exception e) {
doSomethingWithException();
}
doSomethingAfter();
}
doSomethingAfter
将 总是 被调用,无论发生什么。
public void test2() {
try {
doSomething();
} catch (Exception e) {
doSomethingWithException();
} finally {
doSomethingAfter();
}
}
一个return
也挡不住。同样 doSomethingAfter
将 总是 被调用。
public void test3() {
try {
doSomething();
} catch (Exception e) {
doSomethingWithException();
return;
} finally {
doSomethingAfter();
}
}
public int method1()
{
try
{
return 1;
doSomething();
}
catch(Exception e)
{
return 0;
e.printStackTrace();
}
finally
{
System.out.println("Hello user");
}
}
在上述方法中,Hello user 将始终被打印出来。因为存在于 finally 块中的代码将始终执行。 基本上在 JDBC 中,finally 块用于关闭连接。