Java Try with Resources

时间:2020-02-23 14:36:59  来源:igfitidea点击:

今天,我们将研究Java Try with Resources
Java 7的功能之一是用于自动资源管理的try-with-resources语句。

Try with Resources

资源是一个对象,一旦您的程序使用完它就必须关闭它。
例如,用于数据库连接或者套接字连接资源的文件资源或者JDBC资源。
在Java 7之前,没有自动资源管理,一旦完成工作,我们就应该明确关闭资源。
通常,它是在try-catch语句的finally块中完成的。
当我们忘记关闭资源时,此方法曾经导致内存泄漏和性能下降。

让我们看一个伪代码片段,以了解此Java资源尝试功能。

在Java 7之前:

try{
	//open resources like File, Database connection, Sockets etc
} catch (FileNotFoundException e) {
	//Exception handling like FileNotFoundException, IOException etc
}finally{
	//close resources
}

Java 7尝试使用资源实现:

try(//open resources here){
  //use resources
} catch (FileNotFoundException e) {
	//exception handling
}
//resources are closed as soon as try-catch block is executed.

让我们编写一个简单的程序来读取文件并使用Java 6或者更早版本和Java 7 try-with-resources实现打印第一行。

Java 6资源管理示例

package com.theitroad.util;

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

public class Java6ResourceManagement {

	public static void main(String[] args) {
		BufferedReader br = null;
		try {
			br = new BufferedReader(new FileReader("C:\theitroad.txt"));
			System.out.println(br.readLine());
		} catch (IOException e) {
			e.printStackTrace();
		} finally {
			try {
				if (br != null)
					br.close();
			} catch (IOException ex) {
				ex.printStackTrace();
			}
		}
	}
}

Java 7试用资源示例

package com.theitroad.util;

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

public class Java7ResourceManagement {

	public static void main(String[] args) {
		try (BufferedReader br = new BufferedReader(new FileReader(
				"C:\theitroad.txt"))) {
			System.out.println(br.readLine());
		} catch (IOException e) {
			e.printStackTrace();
		}
	}
}

Java尝试利用资源优势

在Java中对资源使用try的一些好处是;

  • 更具可读性的代码,易于编写。

  • 自动资源管理。

  • 代码行数减少。

  • 无需最终阻塞即可关闭资源。

  • 我们可以在try-with-resources语句中用分号分隔开多个资源。
    例如,我们可以编写以下代码:

  • 当在try-with-resources中打开多个资源时,它将以相反的顺序关闭它们,以避免任何依赖关系问题。
    您可以扩展我的资源计划以证明这一点。

Java 7引入了一个新接口" java.lang.AutoCloseable"。
要在try-with-resources中使用任何资源,它必须实现AutoCloseable接口,否则Java编译器将抛出编译错误。

让我们用一个例子来确认这一点:

try (BufferedReader br = new BufferedReader(new FileReader(
				"C:\theitroad.txt"));
				java.io.BufferedWriter writer = java.nio.file.Files.newBufferedWriter(FileSystems.getDefault().getPath("C:\theitroad.txt"), Charset.defaultCharset())) {
			System.out.println(br.readLine());
		} catch (IOException e) {
			e.printStackTrace();
		}

上面程序的输出是:

package com.theitroad.util;

import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;
import java.nio.charset.Charset;
import java.nio.file.FileSystems;

public class Java7ResourceManagement {

	public static void main(String[] args) {

		try (MyResource mr = new MyResource()) {
			System.out.println("MyResource created in try-with-resources");
		} catch (Exception e) {
			e.printStackTrace();
		}
		System.out.println("Out of try-catch block.");
	}

	static class MyResource implements AutoCloseable{

		@Override
		public void close() throws Exception {
			System.out.println("Closing MyResource");
		}

	}
}

从输出中很明显,一旦try-catch块完成,就将调用资源关闭方法。

尝试使用资源异常

在发生异常的情况下,try-catch-finally和try-with-resources之间有一个区别。

如果在try块和finally块中都抛出了异常,则该方法返回在finally块中抛出的异常。

对于try-with-resources,如果在try块和try-with-resources语句中引发了异常,则该方法将返回在try块中引发的异常。

为了更好地阐明这种差异,我们将看到示例代码。

MyResource created in try-with-resources
Closing MyResource
Out of try-catch block.

上面程序的输出是:

package com.theitroad.util;

public class Java7ResourceManagement {

	public static void main(String[] args) throws Exception {
		try {
			tryWithResourceException();
		} catch (Exception e) {
			System.out.println(e.getMessage());
		}
		try {
			normalTryException();
		} catch (Exception e) {
			System.out.println(e.getMessage());
		}
	}

	private static void normalTryException() throws Exception {
		MyResource mr = null;
		try {
			mr = new MyResource();
			System.out.println("MyResource created in the try block");
			if (true)
				throw new Exception("Exception in try");
		} finally {
			if (mr != null)
				mr.close();
		}

	}

	private static void tryWithResourceException() throws Exception {
		try (MyResource mr = new MyResource()) {
			System.out.println("MyResource created in try-with-resources");
			if (true)
				throw new Exception("Exception in try");
		}
	}

	static class MyResource implements AutoCloseable {

		@Override
		public void close() throws Exception {
			System.out.println("Closing MyResource");
			throw new Exception("Exception in Closing");
		}

	}
}