【java9】java9新特性之try-with-resources语句改进_java9

try-with-resources是Java7引入的一个新特性,用于自动管理资源,特别是那些实现了AutoCloseable或Closeable接口的资源。

最常见的例子是文件流、数据库连接等,这些资源在使用完毕后通常需要显式关闭以释放系统资源。

使用try-with-resources语句可以确保这些资源在使用完毕后自动关闭,即使在处理资源时抛出异常也是如此。这大大简化了资源管理代码,并减少了因忘记关闭资源而导致的潜在问题。

在Java9中,try-with-resources语句得到了进一步的改进,主要体现在对多异常的处理和资源变量的声明上。虽然这些改进可能看起来相对较小,但它们确实提高了try-with-resources的灵活性和易用性。

Java7之前

在Java7之前,处理资源(如文件)通常需要显式地打开资源,并在finally块中关闭它。这种方式相对繁琐,且容易出错,特别是当在try块中发生异常时。

package com.morris.java9;

import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;

/**
 * Java6及更早的版本try-with-resources,看看怎么手动关闭流
 */
public class TryWithResources6 {
    public static void main(String[] args) {
        BufferedReader br = null;
        try {
            br = new BufferedReader(new FileReader("example.txt"));
            String line;
            while ((line = br.readLine()) != null) {
                System.out.println(line);
            }
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            if (br != null) {
                try {
                    br.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }
}

Java7

在Java7及更高版本中,使用try-with-resources可以自动管理资源,无需显式关闭。这大大简化了代码,并减少了因忘记关闭资源或处理异常不当而导致的潜在问题。

package com.morris.java9;

import java.io.BufferedReader;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;

/**
 * Java7引入新特性try-with-resources
 */
public class TryWithResources7 {
    public static void main(String[] args) throws FileNotFoundException {
        BufferedReader br = new BufferedReader(new FileReader("example.txt"));
        try (BufferedReader br1 = br) {
            String line;
            while ((line = br1.readLine()) != null) {
                System.out.println(line);
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
        // 在这里,BufferedReader 已经被自动关闭,无需显式调用 br.close()
    }
}

Java9

在Java9中对try-with-resources语句的改进如下:

  1. 多异常处理

在Java9之前,try-with-resources语句中的资源关闭可能会抛出被抑制的异常(suppressed exceptions)。这些被抑制的异常通常是由于在关闭资源时发生的,并且会被原始异常所掩盖。在Java9中,通过改进异常处理机制,开发者可以更容易地访问和处理这些被抑制的异常。

Java9引入了一个新的方法Throwable.getSuppressed(),它返回一个包含所有被抑制异常的Throwable数组。这使得开发者能够检查和处理这些异常,即使它们是在资源关闭期间发生的。

  1. 改进的变量作用域
    如果你有一个资源是final或等效于final变量, 则可以在try-with-resources语句中使用该变量,无需在try-with-resources语句中再声明一个新的变量。

这个改进允许开发者在try块之后立即使用资源变量,而无需将它们声明在更广泛的作用域内。这可以提高代码的局部性和可读性,同时减少不必要的变量声明。

下面是一个简单的示例,展示了在Java9中使用try-with-resources的一些改进:

package com.morris.java9;

import java.io.BufferedReader;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
import java.util.List;
import java.util.stream.Collectors;

/**
 * Java9改进try-with-resources
 */
public class TryWithResources9 {
    public static void main(String[] args) throws FileNotFoundException {
        BufferedReader br = new BufferedReader(new FileReader("example.txt"));
        try (br) {
            List<String> lines = br.lines().collect(Collectors.toList());
            lines.forEach(System.out::println);
        } catch (IOException e) {
            e.printStackTrace();
            // 可以检查和处理被抑制的异常
            Throwable[] suppressed = e.getSuppressed();
            if (suppressed.length > 0) {
                for (Throwable s : suppressed) {
                    s.printStackTrace();
                }
            }
        }
        // 在这里,BufferedReader 已经被自动关闭,无需显式调用 br.close()
    }
}

需要注意的是,只有实现了AutoCloseable或Closeable接口的资源才能与try-with-resources一起使用。大多数标准库中的资源类(如InputStream、OutputStream、Reader、Writer、Connection等)都实现了这些接口,因此可以很容易地与 try-with-resources一起使用。

对比总结

  • 代码简洁性:使用try-with-resources后,代码更加简洁,去除了冗余的finally块和显式资源关闭代码。
  • 错误处理:在try-with-resources之前,如果在finally块中关闭资源时发生异常,可能会掩盖原始异常。使用try-with-resources后,如果有多个资源需要关闭,并且其中某个资源的关闭方法抛出异常,那么该异常会被抑制(suppressed),而原始异常仍然会被抛出。这有助于更好地诊断问题。
  • 资源管理:try-with-resources确保了即使在发生异常的情况下,资源也会被正确关闭。这减少了资源泄露的可能性。
  • 扩展性:try-with-resources可以与多个资源一起使用,只需在try语句的括号中用分号分隔它们即可。这使得管理多个资源变得更加容易。

总的来说,try-with-resources是一个强大的特性,它简化了资源管理代码,提高了代码的可读性和健壮性。在Java7及更高版本中,应该优先使用它来处理需要关闭的资源。