目录
Closeable 和 AutoCloseable
jdk1.7之前
jdk1.7之后
案例代码v1.0
案例代码v2.0
案例代码v3.0
自己写的类,实现AutoCloseable即可。
接口名字 | Closeable | AutoCloseable |
出现时间 | jdk1.5 | jdk1.7 |
调用close | 在jdk1.7前需手动调用,jdk1.7开始,搭配try语句,可以自动。因为继承了AutoCloseable | 搭配try语句,可以自动 |
包 | java.io | java.lang |
这两个接口,Closeable更早出现。他出现的目的,主要也是给那些读写流使用。需手动调用close
FileInputStream, FileOutputStream
BufferedInputStream, BufferedOutputStream
BufferedReader, BufferedWriter
FileReader, FileWriter
InputStream, OutputStream
PrintWriter, PrintStream
Reader, Writer
那时候的代码(jdk1.7之前),一般在finally中调用close(),而且还需要加 if语句判空, 最离谱的是还需要try catch,不然编译都不通过,直接报错。如下:
//JDK1.7之前,需要在finally中手动调用close()
FileInputStream fileInputStream = null;
try {
fileInputStream = new FileInputStream("");
fileInputStream.read();
} catch (IOException e) {
e.printStackTrace();
} finally {
if (null != fileInputStream) {
try {
fileInputStream.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
jdk1.7开始,就可以不需要这样写了。如下:
try (FileInputStream fileInputStream = new FileInputStream("")){
fileInputStream.read();
} catch (IOException e) {
e.printStackTrace();
}
你不需要再在finally里面调用close(),因为当你走出try catch语句块,jvm会帮你调用close。因为这时候有了 AutoCloseable 。
源码中是这样解释:
Closes this resource, relinquishing any underlying resources. This method is invoked automatically on objects managed by the try-with-resources statement.
这个方法会被自动调用。这里提到 try-with-resources 语句,即在try的小括号里声明变量并赋值。就是上面的写法。
AutoCloseable的源码如下:
package java.lang;
public interface AutoCloseable {
void close() throws Exception;
}
Closeable的源码如下:
public interface Closeable extends AutoCloseable {
public void close() throws IOException;
}
下面就来展示一下在实际项目中如何使用 AutoCloseable 这个功能。
自定义一个类,例如:Lock
import java.io.IOException;
public class Lock implements AutoCloseable {
@Override
public void close() throws IOException {
System.out.println("调用了close方法");
}
}
使用Lock
public class Main1 {
public static void main(String[] args) {
try (Lock lock = new Lock()){
System.out.println(".........");
} catch (Exception e) {
e.printStackTrace();
}
}
}
输出:
.........
调用了close方法
Lock类作为redis的分布式锁来使用。例如,分布式下定时任务的控制(schedule)。
import java.io.IOException;
public class Lock implements AutoCloseable {
private String key;
private RedisTemplate redisTemplate;
public Lock(String key,RedisTemplate redisTemplate){
this.key = key;
this.redisTemplate = redisTemplate;
}
@Override
public void close() throws IOException {
redisTemplate.delete(key);
}
}
用 Lock 搭配 redis 来控制 job 执行。代码走出try catch,就会自动调用close,删除key。
import org.springframework.data.redis.core.RedisTemplate;
public class Main1 {
private static RedisTemplate redisTemplate;
public static void main(String[] args) {
String key = "xxx";
try (Lock lock = getLock(key) ){
System.out.println("执行job:start");
} catch (Exception e) {
e.printStackTrace();
}
}
public static Lock getLock(String key){
if(redisTemplate.hasKey(key)){
throw new RuntimeException("job已执行");
}else{
return new Lock(key,redisTemplate);
}
}
}
3.0版是在2.0版基础上,将Lock封装,写个工具类获取Lock。
此处代码有时间再补上。
Java 基础 AutoCloseable & Closeable
浅谈 Java 中的 AutoCloseable 接口 - 知乎
java.io.Closeable接口 - 简书
=======================分割线========================
文章到此已结束,以下是紫薯布丁
import org.springframework.data.redis.core.RedisTemplate;
public class Main1 {
private static RedisTemplate redisTemplate;
public static void main(String[] args) {
String key = "xxx";
try (Lock lock = getLock(key) ){
System.out.println("执行job:start");
} catch (Exception e) {
e.printStackTrace();
}
}
public static Lock getLock(String key){
if(redisTemplate.hasKey(key)){
throw new RuntimeException("job已执行");
}else{
return new Lock(key,redisTemplate);
}
}
}
import java.io.IOException;
public class Lock implements AutoCloseable {
private String key;
private RedisTemplate redisTemplate;
public Lock(String key,RedisTemplate redisTemplate){
this.key = key;
this.redisTemplate = redisTemplate;
}
@Override
public void close() throws IOException {
redisTemplate.delete(key);
}
}
public class Main1 {
public static void main(String[] args) {
try (Lock lock = new Lock()){
System.out.println(".........");
} catch (Exception e) {
e.printStackTrace();
}
}
}
import java.io.IOException;
public class Lock implements AutoCloseable {
@Override
public void close() throws IOException {
System.out.println("调用了close方法");
}
}
package java.lang;
public interface AutoCloseable {
void close() throws Exception;
}
try (FileInputStream fileInputStream = new FileInputStream("")){
fileInputStream.read();
} catch (IOException e) {
e.printStackTrace();
}
//JDK1.7之前,需要在finally中手动调用close()
FileInputStream fileInputStream = null;
try {
fileInputStream = new FileInputStream("");
fileInputStream.read();
} catch (IOException e) {
e.printStackTrace();
} finally {
if (null != fileInputStream) {
try {
fileInputStream.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
public interface Closeable extends AutoCloseable {
public void close() throws IOException;
}