Exception coming out of close() in try-with-resource

ぃ、小莉子 提交于 2020-01-01 04:13:06

问题


I was reading about the try-with-resource in JDK7 and while I was thinking of upgrading my application to run with JDK7 I faced this problem..

When using a BufferedReader for example the write throws IOException and the close throws IOException.. in the catch block I am concerned in the IOException thrown by the write.. but I wouldn't care much about the one thrown by the close..

Same problem with database connections.. and any other resource..

As an example I've created an auto closeable resource:

public class AutoCloseableExample implements AutoCloseable {

    public AutoCloseableExample() throws IOException{
        throw new IOException();
    }

    @Override
    public void close() throws IOException {
        throw new IOException("An Exception During Close");
    }

}

Now when using it:

public class AutoCloseTest {

    public static void main(String[] args) throws Exception {
        try (AutoCloseableExample example = new AutoCloseableExample()) {
            System.out.println(example);

            throw new IOException("An Exception During Read");
        } catch (Exception x) {
            System.out.println(x.getMessage());
        } 
    }

}

how can I distinguish between such exceptions without having to create wrappers for classes such as BufferedReader?

Most of cases I put the resource close in a try/catch inside the finally block without caring much about handling it.


回答1:


Lets consider the class:

public class Resource implements AutoCloseable {

    public Resource() throws Exception {
        throw new Exception("Exception from constructor");
    }

    public void doSomething() throws Exception {
        throw new Exception("Exception from method");
    }

    @Override
    public void close() throws Exception {
        throw new Exception("Exception from closeable");
    }
}

and the try-with-resource block:

    try(Resource r = new Resource()) {
        r.doSomething();
    } catch (Exception ex) {
        ex.printStackTrace();
    }

1. All 3 throw statements enabled.

Message "Exception from constructor" will printed and the exception thrown by constructor will be suppressed, that means you can't catch it.

2. The throw in constructor is removed.

Now the stack trace will print "Exception from method" and "Suppressed: Exception from closeable" below. Here you also can't catch the suppressed exception thrown by close method, but you will be nofitied about the suppressed exception.

3. Throws from constructor and method are removed.

As you have probably already guessed the "Exception from closeable" will be printed.

Important tip: In all of above situations you are actually catching all exceptions, no matter where they were throwed. So if you use try-with-resource block you don't need to wrap the block with another try-catch, it's simply useless.

Hope it helps :)




回答2:


I would suggest using a flag as in the following example:

static String getData() throws IOException {
    boolean isTryCompleted = false;
    String theData = null;
    try (MyResource br = new MyResource();) {

        theData = br.getData();
        isTryCompleted = true;

    } catch(IOException e) {
        if (!isTryCompleted )
            throw e;
        // else it's a close exception and it can be ignored
    }

    return theData;
}

source:Close resource quietly using try-with-resources



来源:https://stackoverflow.com/questions/20657737/exception-coming-out-of-close-in-try-with-resource

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!