2

How to rewrite the following code

try (A a = new A(); B b = new B()) {
//useful work here
}
catch (Exception e) {
//other code
}

using try-catch-finally construction?

If we were only creating one resource there is a nice link here.

Unfortunately, I don't understand how to generalize this when we creating multiple resources.

One thing I don't understand is how do we recognize that something happened to a and didn't happen to 'b' and vice versa.

Ahmad Al-Kurdi
  • 2,248
  • 3
  • 23
  • 39
user23316192
  • 69
  • 1
  • 7
  • 2
    https://docs.oracle.com/javase/tutorial/essential/exceptions/tryResourceClose.html - if specific statements need individual `catch` semantic handling, there should probably be multiple `try..catch` blocks. – user2864740 Dec 25 '17 at 00:40
  • Possible duplicate of [Close multiple resources with AutoCloseable (try-with-resources)](https://stackoverflow.com/questions/30553139/close-multiple-resources-with-autocloseable-try-with-resources) – SurfMan Dec 25 '17 at 00:48
  • @SurfMan no, he needs only try-catch-finally construction – Shmuser Dec 25 '17 at 00:49
  • @SurfMan The question you link does not relate to my question at all. – user23316192 Dec 25 '17 at 00:57
  • @SurfMan I think you did not get the question! – Ahmad Al-Kurdi Dec 25 '17 at 00:58
  • Oh crap, I see where I misread your question. Sorry about that, it's late... I'll try to remove the duplicate flag and upvote @Ahmad Al-Kurdi's answer. – SurfMan Dec 25 '17 at 01:06

1 Answers1

2

There is not general rules, but you have to make sure that you tried to close all resources that you opened, even if do not recognize what happens and in which resource.

 void test() throws Exception {
    A a = null;
    B b = null;

    Exception myException = null;
    try {
        a = new A();
        b = new B();
        //useful work here
    } catch (Exception e) {
        myException = e;
        throw e;
    } finally {
        Throwable tA = handleCloaseable(a);
        Throwable tB = handleCloaseable(b);

        boolean throwIt = false;
        if (myException == null && tA != null || tB != null) {
            myException = new Exception();
            throwIt = true;
        }

        if (tA != null) {
            myException.addSuppressed(tA);
        }
        if (tB != null) {
            myException.addSuppressed(tB);
        }

        if (throwIt) {
            throw myException;
        }
    }
}

Throwable handleCloaseable(AutoCloseable e){ // your resources must implements AutoCloseable or Closeable
    if (e != null) {
        try {
            e.close();
        } catch (Throwable t) {
            return t;
        }
    }
    return null;
}

if any exception occurred when you try to close resources create new Exception if not existed and add the exception the come when you try to close using addSuppressed

Ahmad Al-Kurdi
  • 2,248
  • 3
  • 23
  • 39
  • This is not at all an answer about try-with-resources. – SurfMan Dec 25 '17 at 00:48
  • please read the question again and carefully, he need to convent form try-with-resources to try-catch-finally!. – Ahmad Al-Kurdi Dec 25 '17 at 00:57
  • I misread the quesiton, sorry. I understand it's the other way around. I shouldn't be answering SO on Christmas Eve :) – SurfMan Dec 25 '17 at 01:07
  • No problems :),we here to help. – Ahmad Al-Kurdi Dec 25 '17 at 01:12
  • I'm afraid, but don't some exceptions will be suppressed in your code? In the question that I linked method `addSuppresed` is used just for the case, when there is an exception in the moment of creating object and exception in the moment of working. And also I want to `throw` the exception, not to log the error. So can you please modify your answer? – user23316192 Dec 25 '17 at 04:59
  • @user23316192 I edited my answer to cover your case, and to throw the exception instead of log it – Ahmad Al-Kurdi Dec 25 '17 at 10:20