Java7 老式 Try-Catch-Finally 的资源管理

Java try-with-resources 结构是在 Java 7 中添加的。在 Java 7 之前,管理需要显式关闭的资源有些繁琐。您必须手动处理资源的正确关闭。要正确处理这项任务并不容易。要了解原因,请参阅下面的方法,该方法读取文件并将其打印到 System.out.RTF 中:

package com.hxstrive.jdk7.try_with_resources;

import java.io.FileInputStream;
import java.io.InputStream;

/**
 * JDK7 新特性 try-with-resources
 * @author hxstrive.com
 */
public class TryWithResourcesDemo13 {

    public static void main(String[] args) throws Exception {
        InputStream input = null;
        try {
            input = new FileInputStream("D:\\test.txt"); // 可能会出错,文件不存在
            int data = input.read(); // 读取可能会出错
            while(data != -1){
                System.out.print((char) data);
                data = input.read(); // 读取可能会出错
            }
        } finally {
            if(input != null){
                input.close(); // 关闭资源,也可能会出错
            }
        }
    }

}

正如上面,异常可能发生在 try 代码块中的 3 个地方,以及 finally 代码块中的 1 个地方。

无论 try 代码块是否抛出异常,finally 代码块都会被执行。这意味着,无论 try 代码块中发生了什么,InputStream 都会被关闭。或者说,试图关闭。如果关闭失败,InputStream 的 close() 方法也会抛出异常。

试想一下,异常是从 try 代码块内部抛出的。然后执行 finally 代码块。再假设 finally 代码块也抛出了异常。你认为哪个异常会在调用栈中向上传播?例如:

package com.hxstrive.jdk7.try_with_resources;

import java.io.FileInputStream;
import java.io.InputStream;

/**
 * JDK7 新特性 try-with-resources
 * @author hxstrive.com
 */
public class TryWithResourcesDemo14 {

    public static void main(String[] args) throws Exception {
        InputStream input = null;
        try {
            input = new FileInputStream("D:\\test.txt"); // 可能会出错
            int data = input.read(); // 可能会出错
            while(data != -1){
                System.out.print((char) data);
                data = input.read(); // 可能会出错
            }
            System.out.println();
            throw new Exception("try exception");
        } finally {
            if(input != null){
                input.close(); // 关闭资源,也可能会出错
            }
            throw new Exception("finally exception");
        }
        //结果:
        //You have to believe in yourself. That's the secret of success. Charles Chaplin
        //Genius is one percent inspiration and ninety-nine percent perspiration. Thomas Edison
        //Exception in thread "main" java.lang.Exception: finally exception
        //	at com.hxstrive.jdk7.try_with_resources.TryWithResourcesDemo14.main(TryWithResourcesDemo14.java:28)
    }

}

从上例可知,从 finally 代码块中抛出的异常会被上传到调用堆栈,即使从 try 代码块中抛出的异常可能更适合上传到调用堆栈。

说说我的看法
全部评论(
没有评论
关于
本网站专注于 Java、数据库(MySQL、Oracle)、Linux、软件架构及大数据等多领域技术知识分享。涵盖丰富的原创与精选技术文章,助力技术传播与交流。无论是技术新手渴望入门,还是资深开发者寻求进阶,这里都能为您提供深度见解与实用经验,让复杂编码变得轻松易懂,携手共赴技术提升新高度。如有侵权,请来信告知:hxstrive@outlook.com
公众号