Java try-finally
块
原文: https://howtodoinjava.com/java/exception-handling/try-catch-finally/
Java try
,catch
和finally
块有助于编写可能在运行时引发异常的应用程序代码,并为我们提供了通过执行替代应用程序逻辑或优雅地处理异常,以向用户报告。 它有助于防止丑陋的应用程序崩溃。
1. Java try
,catch
和finally
块
1.1 try
块
try
块包含应在正常条件下运行的应用程序代码。 例如,读取文件,写入数据库或执行复杂的业务操作。
try
块写为try
关键字,后跟花括号。
try {
//application code
}
1.2 catch
块
可选的catch
块位于try
块之后,并且必须处理try
块引发的受检异常以及任何可能的非受检异常。
try {
//code
}
catch(Exception e) {
//handle exception
}
应用程序可能会以 N 种不同方式出错。 这就是为什么我们可以将多个catch
块与单个try
块相关联的原因。 在每个catch
块中,我们可以以一种独特的方式处理一个或多个特定的异常。
当一个catch
块处理异常时,不执行下一个catch
块。 控制直接从已执行的catch
块转移到执行器的其余部分,包括finally
块。
try {
//code
}
catch(NullPointerException e) {
//handle exception
}
catch(NumberFormatException e) {
//handle exception
}
catch(Exception e) {
//handle exception
}
1.3 finally
块
可选的finally
块使我们有机会在每次try-catch
块完成时运行我们要执行的代码 - 有错误或无错误。
即使我们未能在catch
块中成功处理异常,也可以保证finally
块语句的执行。
try {
//open file
//read file
}
catch(Exception e) {
//handle exception while reading the file
}
finally {
//close the file
}
1.4 仅try
块是强制性的
请注意,只有try
块是必需的,而catch
和finally
块是可选的。 使用try
块,我们可以根据需要使用catch
块或finally
块。
下面可能用 Java 给出两种组合。 这两个版本均有效。
try {
}
catch(Exception e) {
}
try {
}
finally {
}
2. Java 异常处理如何工作?
在正常情况下,当运行时发生异常时,JVM 将错误信息包装在Throwable
子类型的实例中。 此异常对象类似于其他 Java 对象,并且具有字段和方法。
唯一的区别是 JVM 检查它们的存在并将控制权传递给catch
块,该块可以处理异常类型或其父类类型。
try catch finally
流
当在应用程序中找不到异常的catch
块时,未捕获的异常由 JVM 级别的默认异常处理程序处理。 它向用户报告异常并终止应用程序。
3. 带有try
,catch
和finally
块的不同执行流程
我们来看一些示例,以了解在不同情况下执行流程的流程。
3.1 try
,catch
和finally
块 – 没有发生异常
如果没有发生异常,那么 JVM 将仅执行finally
块。 catch
块将被跳过。
try
{
System.out.println("try block");
}
catch (Exception e)
{
System.out.println("catch block");
}
finally
{
System.out.println("finally block");
}
程序输出。
try block
finally block
3.2 try
,catch
和finally
块 – 发生异常
如果try
块中发生异常,则 JVM 将首先执行catch
块,然后执行finally
。
try
{
System.out.println("try block");
throw new NullPointerException("Null occurred");
}
catch (Exception e)
{
System.out.println("catch block");
}
finally
{
System.out.println("finally block");
}
程序输出:
try block
catch block
finally block
3.3 try
和finally
块 – 未处理异常
如果提供的catch
块未处理异常,则 JVM 默认异常处理程序将处理该异常。 在这种情况下,将执行finally
块,然后执行默认的异常处理机制。
try
{
System.out.println("try block");
throw new NullPointerException("Null occurred");
}
finally
{
System.out.println("finally block");
}
程序输出:
try block
finally block
Exception in thread "main"
java.lang.NullPointerException: Null occurred
at com.howtodoinjava.Main.main(Main.java:12)
3.4 try
,catch
和finally
块 – 多个catch
块
如果有多个catch
块与try
块相关联,则异常由顺序处理的第一个catch
块处理,该异常可以处理异常类型或其父类型。
例如,处理IOException
的catch
块可以处理FileNotFoundException
类型的异常,这也是因为FileNotFoundException extends IOException
。
try
{
System.out.println("try block");
throw new NullPointerException("null occurred");
}
catch (NumberFormatException e)
{
System.out.println("catch block 1");
}
catch (NullPointerException e)
{
System.out.println("catch block 2");
}
catch (Exception e)
{
System.out.println("catch block 3");
}
finally
{
System.out.println("finally block");
}
程序输出:
try block
catch block 2
finally block
3.5 try
,catch
和finally
块 – catch
块引发异常
在catch
块中处理另一个异常时,有时可能会出现异常。 它将如何处理?
如果catch
块中有异常,则将执行转移到与各个catch
块相关联的finally
块(如果有)。 然后,将该异常传播到方法调用栈中,以找到可以处理此异常的catch
块。
如果找到了此类catch
块,则处理异常,否则 JVM 默认异常处理程序将处理异常并终止应用程序。
try
{
System.out.println("try block");
throw new NullPointerException("NullPointerException occured");
}
catch (NullPointerException e)
{
System.out.println("catch block 1");
throw new NumberFormatException("NumberFormatException occurred");
}
catch (Exception e)
{
System.out.println("catch block 2");
}
finally
{
System.out.println("finally block");
}
程序输出:
try block
catch block 1
finally block
Exception in thread "main"
java.lang.NumberFormatException: NumberFormatException occurred
at com.howtodoinjava.Main.main(Main.java:18)
4. try-with-resources
对于可关闭的资源(例如流),Java SE 7 引入了try-with-resources
语句,这是在上述情况下处理异常的推荐方法。 在这种方法中,我们不需要关闭流,而 JVM 会为我们完成它。 它消除了finally
块的需要。
在try-with-resources
中,资源在小括号内的try
块中打开,finally
块完全消失了。
try (BufferedReader br = new BufferedReader(new FileReader("C:/temp/test.txt")))
{
String sCurrentLine;
while ((sCurrentLine = br.readLine()) != null)
{
System.out.println(sCurrentLine);
}
}
catch (IOException e)
{
e.printStackTrace();
}
阅读更多信息: Java 7 try-with-resource
学习愉快!