Java 最后,有时我会感到困惑
今天在大学里,我们谈了一些关于Java 最后,有时我会感到困惑,java,exception,exception-handling,try-catch,finally,Java,Exception,Exception Handling,Try Catch,Finally,今天在大学里,我们谈了一些关于尝试,捕获和最终。 我对这两个例子感到困惑: PrintWriter out = null; try { out = new PrintWriter(...); // We open file here } catch (Exception e) { e.printStackTrace(); } finally { // And we close it here out.close(); } 最后在中关闭文件与按此方式关闭文件有什么区别: PrintW
尝试
,捕获
和最终
。
我对这两个例子感到困惑:
PrintWriter out = null;
try {
out = new PrintWriter(...); // We open file here
} catch (Exception e) {
e.printStackTrace();
} finally { // And we close it here
out.close();
}
最后在中关闭文件与按此方式关闭文件有什么区别:
PrintWriter out = null;
try {
out = new PrintWriter(...); // We open file here
} catch (Exception e) {
e.printStackTrace();
}
out.close();
捕获后的这段代码将始终执行
你能给我一些很好的例子说明当我们最后使用时
和当我们把代码放在catch之后时的区别吗?我知道finally将始终执行,但程序也将在catch块之后继续运行。如果代码抛出错误,则仍然会有不同。这不会在代码中捕获,因此try/catch/finally
之后的任何部分都不会被捕获。如果它是finally
的一部分,即使出现错误
,它仍将被执行
其次,如果出于任何原因e.printStackTrace()
抛出异常(尽管这非常罕见),同样的情况也会发生-最终仍将执行
总的来说,最后
是一种非常安全的方式,无论发生什么情况都可以释放资源。自Java 7以来,支持的安全性更高,因为它可以轻松管理关闭操作期间抛出的多个异常。在本例中,它看起来像:
try (PrintWriter out = new PrintWriter(...)) {
// do whatever with out
}
catch (Exception e) {
e.print... (whatever)
}
// no need to do anything else, close is invoked automatically by try block
编辑:还要注意,您的代码不是真正正确的(无论是哪个版本)。如果PrintWriter
构造函数抛出异常,那么out.close()行将在NullPointerException
上失败,如果try
块内发生未捕获的错误,或者即使catch
块内发生错误,也不会执行catch之后的“代码片段”,但是最后将执行块
最后
将始终执行
从Java文档中:
当try块退出时,finally块始终执行。这
确保即使出现意外错误,也会执行finally块
出现异常。但最后,它不仅适用于例外情况
处理-它允许程序员避免清理代码
由于返回、继续或中断而意外绕过。清理
finally块中的代码始终是一种良好的实践,即使没有
预计会出现例外情况
若catch块中的某个内容将抛出异常怎么办?out.close将不执行。您还可以使用“”,以确保所有资源在使用后都已关闭。试试这个例子:
public static void withFinnaly() {
try {
throwException();
System.out.println("This won't execute");
} catch (Exception e) {
System.out.println("Exception is caught");
throwException();
} finally {
System.out.println("Finally is always executed," +
" even if method in catch block throwed Exception");
}
}
public static void withOutFinnaly() {
try {
throwException();
System.out.println("This won't execute");
} catch (Exception e) {
System.out.println("Exception is caught");
throwException();
}
System.out.println("Looks like we've lost this... " +
"This wont execute");
}
public static void throwException() throws RuntimeException {
throw new RuntimeException();
}
如果PrintWriter
的构造函数中发生异常,则第二个示例可能会抛出不需要的NullPointerException
另一种可能性是out.close()代码>将抛出一个未捕获的错误
如果将代码移动到finally
块中,则无论try块是否成功,它都将始终执行。如果try
-块引发未捕获的异常,则这一点特别有用。在第二个示例中,这将导致不执行out.close()
,而对于finally块,即使try
块抛出未捕获的错误,也会执行该块。finally的正常用例是当您不想用相同的方法捕获异常时
在这种情况下,您可以使用try with finally块,而无需捕获。通过这种方式,您可以确保关闭资源,而不必捕获方法本身的异常。虽然本身没有完整的答案,但这两个使用try finally
(mis)的示例可能会有所启发:
public class JavaApplication3
{
static int foo()
{
try
{
return 6;
}
finally
{
return 4;
}
}
public static void main(String[] args)
{
System.out.println("foo: " + foo());
}
}
public class JavaApplication3
{
static int foo()
{
try
{
throw new Exception();
}
finally
{
return 4;
}
}
public static void main(String[] args)
{
System.out.println("foo: " + foo());
}
}
两个程序都输出4
原因可在上找到
带有finally块的try语句通过首先执行try块来执行。还有一个选择:
•如果try块的执行由于抛出值而突然完成
五、 然后有一个选择:
[…]
–如果V的运行时类型与可捕获的分配不兼容
try语句的任何catch子句的异常类,然后
块被执行。然后有一个选择:
[…]
›如果finally块由于原因S而突然完成,则try语句
由于原因S而突然完成(并且值V的抛出被丢弃并且
已忘记)。
•如果try块的执行由于任何其他原因而突然完成,则执行finally块,然后有一个选择:
–如果finally块正常完成,则try语句完成
由于某种原因而突然
–如果finally块由于原因S而突然完成,则try语句
由于原因S而突然完成(并且原因R被丢弃)。
编辑矿山
假设返回是一种完成try
或finally
块的突然方式。在Java中,源代码:
void foo()
{
try {
if (W())
return;
}
catch (FooException ex) {
if (X())
throw;
}
finally {
Y();
}
Z();
}
将由编译器转换为:
void foo()
{
try {
if (W()) {
Y();
return;
}
}
catch (FooException ex) {
if (X()) {
Y();
throw;
}
}
catch {
Y();
throw;
}
Y();
Z();
}
其结果是导致Finally块中的代码在
控件可能离开方法的所有位置。任何尝试块
具有finally
但不是catch-all处理程序的处理程序相当于具有立即抛出的catch-all处理程序的处理程序(处理器可以在catch-all处理程序之前插入finally
代码的副本)。一个较小的示例:
PrintWriter out = null;
try {
out = new PrintWriter();
out.print(data);
} finally {
out.close();
}
在这里,我们不捕获任何异常(由调用方处理),但我们确实希望关闭编写器无论我们是否
- 通过
try
块正常运行,或
- 通过例外情况离开
在这两种情况下,finally
中的代码作为离开块的一部分执行
这里,我们捕获异常的子集:
PrintWriter out = null;
try {
out = new PrintWriter();
out.print(data);
} catch (IOException e) {
log(e);
} finally {
out.close();
}
do_something_else();
这里有三种可能的路径:
- 正常执行
try
部分,foll