Try-with-resources and return statements in java

前端 未结 3 650
Happy的楠姐
Happy的楠姐 2020-12-03 09:56

I\'m wondering if putting a return statement inside a try-with-resources block prevents the resource to be automatically closed.

try(Connec         


        
相关标签:
3条回答
  • 2020-12-03 10:15

    The resource will be closed automatically (even with a return statement) since it implements the AutoCloseable interface. Here is an example which outputs "closed successfully":

    public class Main {
    
        public static void main(String[] args) {
            try (Foobar foobar = new Foobar()) {
                return;
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }
    
    class Foobar implements AutoCloseable {
    
        @Override
        public void close() throws Exception {
            System.out.println("closed successfully");
        }
    }
    
    0 讨论(0)
  • 2020-12-03 10:15

    The AutoCloseable interface can make the execution order of code confusing at first glance. Lets run through this with an example:

    public class Main {
    
        // An expensive resource which requires opening / closing
        private static class Resource implements AutoCloseable {
    
            public Resource() {
                System.out.println("open");
            }
            
            @Override public void close() throws Exception {
                System.out.println("close");
            }
        }
        
        // find me a number!
        private static int findNumber() {
            // open the resource
            try(Resource resource = new Resource()) {
                // do some business logic (usually involving the resource) and return answer
                return 2 + 2;
            } catch(Exception e) {
                // resource encountered a problem
                throw new IllegalStateException(e);
            }
        }
        
        public static void main(String[] args) {
            System.out.println(findNumber());
        }
    }
    

    The above code attempts to open some Resource and conduct some business logic using the resource (just some arithmetic in this case). Running the code will print:

    open
    close
    4
    

    Therefore the Resource is closed before exiting the try-with-resource block. To make it clear what exactly is going on, lets reorganise the findNumber() method.

        private static int findNumber() {
            // open the resource
            int number;
            try(Resource resource = new Resource()) {
                // do some business logic and return answer
                number = 2 + 2;
            } catch(Exception e) {
                // resource encountered a problem
                throw new IllegalStateException(e);
            }
            return number;
        }
    

    Conceptually, this is what happens under the hood when return is placed inside a try-with-resource block. The return operation is moved to after the try-with-resource block to allow the AutoCloseable object to close before returning.

    Therefore we can conclude that a return operation inside a try-with-resource block is just syntactic sugar and you need not worry about returning before an AutoCloseable has closed.

    0 讨论(0)
  • 2020-12-03 10:24

    Based on Oracle's tutorial, "[the resource] will be closed regardless of whether the try statement completes normally or abruptly". It defines abruptly as from an exception.

    Returning inside the try is an example of abrupt completion, as defined by JLS 14.1.

    0 讨论(0)
提交回复
热议问题