【java】Try With Resources

     英文原文:https://www.journaldev.com/592/java-try-with-resources

     今天和大家聊一下java中的 “try with resource”用法。通过“try-with-resource”实现资源自动管理,是 java 7的一个重要特性。

   (译者注:此处resource,指程序运行中打开的资源,比如:java stream、socket 等)

 

目录

    1.try with resource 介绍

        1.1 java 6 资源管理 举例

        1.2 java 7 try with resource 举例 

    2.java try with resource 的好处

    3.try with resource 的 异常处理

 

1.try with resource

【java】Try With Resources_第1张图片

       本文"resource"指:程序运行结束时,同时必须要关闭的对象。比如,文件资源(java io)或者 数据库连接的JDBC资源 或者 socket连接资源。

       在java 7之前,“自动资源管理”的概念是不存在的,且当此“资源”在代码中完成任务后,需明确在try-catch-finally结构的finally块关闭它。当忘记手动关闭资源时,通常会导致内存泄漏以及性能损失。

      下面通过一段伪代码来理解 try-with-resource 特性。

       1)java 7 之前

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

    2)java 7 实现 try-with-resource

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

 

     下面分别使用java6及更老的版本 和 java7 的try-with-resource 来从文件中读取数据并打印。

      java 6 资源管理示例:

package com.journaldev.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:\\journaldev.txt"));
			System.out.println(br.readLine());
		} catch (IOException e) {
			e.printStackTrace();
		} finally {
			try {
				if (br != null)
					br.close();  //attention here
			} catch (IOException ex) {
				ex.printStackTrace();
			}
		}
	}
}

      java 7 try-with-resource 示例:

package com.journaldev.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:\\journaldev.txt"))) {
			System.out.println(br.readLine());
		} catch (IOException e) {
			e.printStackTrace();
		}
	}
}

 

2.java try with resource 的好处

     1)代码可读性更强且容易编写

     2)资源自动管理(释放)

     3)代码行数减少

     4)不再需要finally代码块即可释放资源

     5)在try-with-resource声明中,可以通过分号分隔来开启多个资源。如下代码所示:

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

     6)当try-with-resource中打开了多个资源,会按照相反的顺序关闭来避免依赖产生的问题。

 

       java 7 介绍了新的接口“java.lang.AutoCloseable”。如果使用try-with-resource,则必须实现AutoCloseable接口,否则编译时将抛出异常。参考如下代码:

package com.journaldev.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");
		}

	}
}

      上述程序的输出如下:

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

        如上可见,当try-catch块执行完成后,资源回收的方法被自动调用了。

 

3.try with resource 的 异常处理

     下面说明“try-catch-finally”和“try-with-resources”在异常处理上的不同。

      1)如果在try块和finally块同时抛出异常,方法返回的异常信息来源于finally块。

      2)对于“try-with-resources”,如果在try块和“try-with-resources”中同时抛出异常,方法返回的异常,是try块中的异常。

     为了更好的理解2种不同,参考如下代码:

package com.journaldev.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");
		}

	}
}

      上述程序的输出为:

MyResource created in try-with-resources
Closing MyResource
Exception in try
MyResource created in the try block
Closing MyResource
Exception in Closing

      由此证明了上述在异常处理上的不同。

 

     that's all for the java 7 try-with-resources.

     2019.06.23 周日晚

你可能感兴趣的:(【java】Try With Resources)