Java try-finally块

Java try-finally

原文: https://howtodoinjava.com/java/exception-handling/try-catch-finally/

Java trycatchfinally块有助于编写可能在运行时引发异常的应用程序代码,并为我们提供了通过执行替代应用程序逻辑或优雅地处理异常,以向用户报告。 它有助于防止丑陋的应用程序崩溃。

1. Java trycatchfinally

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块是必需的,而catchfinally块是可选的。 使用try块,我们可以根据需要使用catch块或finally块。

下面可能用 Java 给出两种组合。 这两个版本均有效

try {

}
catch(Exception e) {

}

try {

}
finally {

}

2. Java 异常处理如何工作?

在正常情况下,当运行时发生异常时,JVM 将错误信息包装在Throwable子类型的实例中。 此异常对象类似于其他 Java 对象,并且具有字段和方法。

唯一的区别是 JVM 检查它们的存在并将控制权传递给catch块,该块可以处理异常类型或其父类类型

try catch finally flow

try catch finally

当在应用程序中找不到异常的catch块时,未捕获的异常由 JVM 级别的默认异常处理程序处理。 它向用户报告异常并终止应用程序。

3. 带有trycatchfinally块的不同执行流程

我们来看一些示例,以了解在不同情况下执行流程的流程。

3.1 trycatchfinally块 – 没有发生异常

如果没有发生异常,那么 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 trycatchfinally块 – 发生异常

如果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 tryfinally块 – 未处理异常

如果提供的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 trycatchfinally块 – 多个catch

如果有多个catch块与try块相关联,则异常由顺序处理的第一个catch块处理,该异常可以处理异常类型或其父类型。

例如,处理IOExceptioncatch块可以处理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 trycatchfinally块 – 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

学习愉快!