java:AutoCloseable接口使用

如果你不相信努力和时光,那么成果就会是第一个选择辜负你的。不要去否定你自己的过去,也不要用你的过去牵扯你现在的努力和对未来的展望。不是因为拥有希望你才去努力,而是去努力了,你才有可能看到希望的光芒。java:AutoCloseable接口使用,希望对大家有帮助,欢迎收藏,转发!站点地址:www.bmabk.com,来源:原文

java:AutoCloseable接口使用

1 前言

AutoCloseable接口,在try-with-resources代码块退出时,会自动调用接口的close方法,避免资源耗尽的异常等情况。

参考java文档,如下:

An object that may hold resources (such as file or socket handles) until it is closed. 
The close() method of an AutoCloseable object is called automatically 
when exiting a try-with-resources block for which the object 
has been declared in the resource specification header. 
This construction ensures prompt release, avoiding resource exhaustion exceptions and errors that may otherwise occur.

2 使用

public class TestAutoC {

    public void run1(){
        try(ACL acl = new ACL(); BCL bcl = new BCL()){
            acl.run();
            bcl.run();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    public void run2(){
        ACL acl = new ACL();
        BCL bcl = new BCL();
        try {
            acl.run();
            bcl.run();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    public void run3(){
        ACL acl;
        BCL bcl;
        try {
            acl = new ACL();
            bcl = new BCL();
            acl.run();
            bcl.run();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    public void run4(){
        try(ACL acl = new ACL(); BCL bcl = new BCL()){
            acl.run();
            int i = 0;
            if(i == 0){
                throw new RuntimeException("unknown error");
            }
            bcl.run();
        }
        catch (Exception e) {
            e.printStackTrace();
            throw (RuntimeException)e;
        }

    }

    public static void main(String[] args) {
        TestAutoC autoC = new TestAutoC();
        autoC.run1();
        System.out.println("*************");
        autoC.run2();
        System.out.println("*************");
        autoC.run3();
        System.out.println("*************");
        autoC.run4();
    }

}


class ACL implements AutoCloseable{
    {
        System.out.println("ACL instance init");
    }

    public void run(){
        System.out.println("ACL run");
    }

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

class BCL implements AutoCloseable{
    {
        System.out.println("BCL instance init");
    }

    public void run(){
        System.out.println("BCL run");
    }

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

执行结果可知,在try-with-resources代码块结束时才会自动调用close方法(try代码块中的方法已执行),而仅仅在try代码块中执行(非try-with-resources)不会自动调用close方法,且使用了try-with-resources代码块时,即便catch抛出异常,也会执行close方法:

ACL instance init
BCL instance init
ACL run
BCL run
BCL close
ACL close
*************
ACL instance init
BCL instance init
ACL run
BCL run
*************
ACL instance init
BCL instance init
ACL run
BCL run
*************
ACL instance init
BCL instance init
ACL run
BCL close
ACL close
java.lang.RuntimeException: unknown error
	at com.xiaoxu.test.TestAutoC.run4(TestAutoC.java:48)
	at com.xiaoxu.test.TestAutoC.main(TestAutoC.java:67)
Exception in thread "main" java.lang.RuntimeException: unknown error
	at com.xiaoxu.test.TestAutoC.run4(TestAutoC.java:48)
	at com.xiaoxu.test.TestAutoC.main(TestAutoC.java:67)

并且上述close方法调用的顺序是,try-with-resources代码块中顺序定义靠后的资源,优先调用close方法释放。在使用try-with-resources代码块时,须加上catch语句,用于捕获close方法的Exception异常,否则提示:Unhandled exception from auto-closeable resource: java.lang.Exception(或者方法直接显示声明throws Exception,在外层逻辑接收此异常)。

当然,如果资源使用时,需要添加其他操作,那么可以采用在try代码块中嵌入另外一个资源的try代码块的方式,依然可以达到最外层嵌套的try-with-resources代码块最后调用close方法的效果:

public void run5() throws Exception{
    try(ACL acl = new ACL()){
        acl.run();
        System.out.println("acl run over");
        try(BCL bcl = new BCL()){
            bcl.run();
        }
        System.out.println("bcl run over");
    }
}

执行结果如下:

ACL instance init
ACL run
acl run over
BCL instance init
BCL run
BCL close
bcl run over
ACL close

需注意,若使用嵌套的try-with-resources代码块释放资源时,若外层调用抛出异常,则内部的try-with-resources代码块还未开始执行,也就不会有资源的定义和释放,若内层try-with-resources代码块抛出异常,也不会影响内层和外层已定义资源的释放,所以不会出现问题,如下可示:

示例1:

public void run6() throws Exception{
    try(ACL acl = new ACL()){
        acl.run();
        int i = 0;
        if(i == 0){
            throw new RuntimeException("unknown error");
        }
        try(BCL bcl = new BCL()){
            bcl.run();
        }
    }
}

执行结果:

ACL instance init
ACL run
ACL close
Exception in thread "main" java.lang.RuntimeException: unknown error
	at com.xiaoxu.test.TestAutoC.run6(TestAutoC.java:81)
	at com.xiaoxu.test.TestAutoC.main(TestAutoC.java:114)

示例2:

public void run7() throws Exception{
    try(ACL acl = new ACL()){
        acl.run();
        int i = 0;
        try(BCL bcl = new BCL()){
            bcl.run();
            if(i == 0){
                throw new RuntimeException("unknown error");
            }
        }
    }
}

执行结果:

ACL instance init
ACL run
BCL instance init
BCL run
BCL close
ACL close
Exception in thread "main" java.lang.RuntimeException: unknown error
	at com.xiaoxu.test.TestAutoC.run7(TestAutoC.java:70)
	at com.xiaoxu.test.TestAutoC.main(TestAutoC.java:117)

实际运用场景中,比如RabbitMQ消息中,根据官方文档亦有提示,

The connection abstracts the socket connection, and takes care of protocol version negotiation and authentication and so on for us. Here we connect to a RabbitMQ node on the local machine - hence the localhost. If we wanted to connect to a node on a different machine we'd simply specify its hostname or IP address here.

Next we create a channel, which is where most of the API for getting things done resides. Note we can use a try-with-resources statement because both Connection and Channel implement java.lang.AutoCloseable. This way we don't need to close them explicitly in our code.

To send, we must declare a queue for us to send to; then we can publish a message to the queue, all of this in the try-with-resources statement:

即RabbitMQ中,获取Connection和Channel都可以在try-with-resources代码块中使用,因为它们都实现了java.lang.AutoCloseable接口,无需再显示的调用close方法了,其余常见的使用场景,还有数据库的Connection、Statement、ResultSet等资源的自动关闭等等:

ConnectionFactory factory = new ConnectionFactory();
factory.setHost("localhost");
try (Connection connection = factory.newConnection();
     Channel channel = connection.createChannel()) {

}

RabbitMQ官网地址:

https://www.rabbitmq.com/
https://www.rabbitmq.com/tutorials/tutorial-one-java.html

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

文章由极客之音整理,本文链接:https://www.bmabk.com/index.php/post/192076.html

(0)
飞熊的头像飞熊bm

相关推荐

发表回复

登录后才能评论
极客之音——专业性很强的中文编程技术网站,欢迎收藏到浏览器,订阅我们!