目录

Closeable 和 AutoCloseable

jdk1.7之前

jdk1.7之后

案例代码v1.0

案例代码v2.0

案例代码v3.0 


省流:

自己写的类,实现AutoCloseable即可。

作用:代码走出try catch语句块,自动调用close。

正文:

Closeable 和 AutoCloseable

接口名字CloseableAutoCloseable
出现时间jdk1.5jdk1.7
调用close在jdk1.7前需手动调用,jdk1.7开始,搭配try语句,可以自动。因为继承了AutoCloseable搭配try语句,可以自动
java.iojava.lang

这两个接口,Closeable更早出现。他出现的目的,主要也是给那些读写流使用。需手动调用close

FileInputStream, FileOutputStream

BufferedInputStream, BufferedOutputStream

BufferedReader, BufferedWriter

FileReader, FileWriter

InputStream, OutputStream

PrintWriter, PrintStream

Reader, Writer

jdk1.7之前

那时候的代码(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之后

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 这个功能。

案例代码v1.0

自定义一个类,例如: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方法

案例代码v2.0

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);
        }
    }
}

案例代码v3.0 

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;
}
 

Logo

开放原子开发者工作坊旨在鼓励更多人参与开源活动,与志同道合的开发者们相互交流开发经验、分享开发心得、获取前沿技术趋势。工作坊有多种形式的开发者活动,如meetup、训练营等,主打技术交流,干货满满,真诚地邀请各位开发者共同参与!

更多推荐