Java 简明教程

Java - Try with Resources

Try with Resources

Java 中的 try-with-resources 语句是一个 try statement,用于声明一个或多个资源,例如流、套接字、数据库、连接等。这些资源必须在程序完成后关闭。try-with-resources 语句将在其结尾关闭这些资源。

try-with-resources 功能于 Java7 中引入。try-with-resources 也可以用 try-catch-finally 作为资源对象进行替代。

try-with-resources 语句也被称为“自动资源管理”,它在 Java7 中引入。如果使用资源对象,此语句可以替代 try-catch-finally 语句。

Syntax of Try with Resources

若要使用此语句,只需将所需资源声明在括号内,创建的资源将在块的末尾自动关闭。下面是 try-with-resources 语句的语法:

try(resources declarations) {
    // use of the resources
}
catch(Exception e) {
    // exception handling
}

例如,使用 try-with-resources 打开文件:

try(FileReader fr = new FileReader("file path")) {
   // use the resource
   } catch () {
      // body of catch
   }
}

以下是使用 try-with-resources 语句读取文件中的数据的程序。

Example: Try with Resources in Java

在该程序中,我们使用 try with resources 语句创建 FileReader 对象。在 try 语句中声明 FileReader fr,并且我们不需要在 finally 块中记住关闭它,因为 JVM 会自动关闭它,因此不存在内存泄漏或丢失连接的可能性。

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

public class Try_withDemo {

   public static void main(String args[]) {
      try(FileReader fr = new FileReader("E://file.txt")) {
         char [] a = new char[50];
         fr.read(a);   // reads the contentto the array
         for(char c : a)
         System.out.print(c);   // prints the characters one by one
      } catch (IOException e) {
         e.printStackTrace();
      }
   }
}

Try with Resources having Multiple Resources

你也可以在 try 块内声明多个资源。考虑下面的示例:

// This example is to use Try with Resources
// with multiple  Resources
import java.io.BufferedReader;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.PrintWriter;
import java.io.IOException;

public class Main {
  public static void main(String[] args) {
    // try block with multiple resources
    try (
      FileReader fileReader = new FileReader("file1.txt");
      BufferedReader bufferedReader = new BufferedReader(fileReader);
      FileWriter fileWriter = new FileWriter("file2.txt");
      PrintWriter printWriter = new PrintWriter(fileWriter)
    ) {
      String line;
      while ((line = bufferedReader.readLine()) != null) {
        // Read content line by line and write it
        // to the output (file2.txt) file
        printWriter.println(line);
      }
      System.out.println("Content copied.");
    } catch (IOException e) {
      e.printStackTrace();
    }
  }
}

Example: Without Try with Resources

在以下程序中,我们使用 FileReader 从文件中读取数据,并使用 finally 块关闭它。在该程序中,我们使用 try 块创建 FileReader 对象。FileReader fr,引用被声明在 try 块的外部,这样它就可以在 try 块的外部访问,并且我们不需要记住在 finally 块中关闭它或在程序退出之前关闭它,这样就不会存在内存泄漏或丢失连接的可能性。

import java.io.File;
import java.io.FileReader;
import java.io.IOException;

public class ReadData_Demo {

   public static void main(String args[]) {
      FileReader fr = null;
      try {
         File file = new File("file.txt");
         fr = new FileReader(file); char [] a = new char[50];
         fr.read(a);   // reads the content to the array
         for(char c : a)
         System.out.print(c);   // prints the characters one by one
      } catch (IOException e) {
         e.printStackTrace();
      }finally {
         try {
            fr.close();
         } catch (IOException ex) {
            ex.printStackTrace();
         }
      }
   }
}

Try with Resources: Points to Remember

在使用 try-with-resources 语句时,需要注意以下几点。

  1. 要使用带有 try-with-resources 语句的类,它应该实现 AutoCloseable 接口并自动在运行时调用它的 close() 方法。

  2. 你可以在 try-with-resources 语句中声明多个类。

  3. 当你在 try-with-resources 语句的 try 块中声明多个类时,这些类将按相反的顺序关闭。

  4. 除了括号内的资源声明之外,其他所有内容都与 try 块的 normal try/catch 块相同。

  5. 在 try 块中声明的资源在 try-block 开始之前被实例化。

  6. 在 try 块中声明的资源隐式声明为 final。

try with resources improvement with Java 9

在 Java 9 之前,资源应在如下面的给定示例中所示 try 语句之前或内部声明。在此示例中,我们将使用 BufferedReader 作为资源来读取字符串,然后关闭 BufferedReader。

Before Java 9

import java.io.BufferedReader;
import java.io.IOException;
import java.io.Reader;
import java.io.StringReader;

public class Tester {
   public static void main(String[] args) throws IOException {
      System.out.println(readData("test"));
   }
   static String readData(String message) throws IOException {
      Reader inputString = new StringReader(message);
      BufferedReader br = new BufferedReader(inputString);
      try (BufferedReader br1 = br) {
         return br1.readLine();
      }
   }
}

让我们编译并运行上述程序,这将生成以下结果 −

test

在这里我们可以在 try 语句中声明资源 br1 然后使用它。在 Java9 中,我们不再需要声明 br1 了并且以下程序将给出相同的结果。

Java 9 onwards

import java.io.BufferedReader;
import java.io.IOException;
import java.io.Reader;
import java.io.StringReader;

public class Tester {
   public static void main(String[] args) throws IOException {
      System.out.println(readData("test"));
   }
   static String readData(String message) throws IOException {
      Reader inputString = new StringReader(message);
      BufferedReader br = new BufferedReader(inputString);
      try (br) {
         return br.readLine();
      }
   }
}

让我们编译并运行上述程序,这将生成以下结果 −

test