What is the point of the finally block?

后端 未结 16 1108
长情又很酷
长情又很酷 2020-12-30 20:19

Syntax aside, what is the difference between

try {
}
catch() {
}
finally {
    x = 3;
}

and

try {
}
catch() {
}

x = 3;


        
相关标签:
16条回答
  • 2020-12-30 20:51

    Finally blocks permit you, as a developer, to tidy up after yourself, regardless of the actions of preceeding code in the try{} block encountered errors, and have others have pointed out this, is falls mainly under the umbrella of freeing resources - closing pointers / sockets / result sets, returning connections to a pool etc.

    @mats is very correct that there is always the potential for "hard" failures - finally blocks shouldn't include mission critical code, which should always be done transactionally inside the try{}

    @mats again - The real beauty is that it allows you throw exceptions back out of your own methods, and still guarantee that you tidy up:

    try
    {
    StreamReader stream = new StreamReader("foo.bar");
    mySendSomethingToStream(stream);
    }
    catch(noSomethingToSendException e) {
        //Swallow this    
        logger.error(e.getMessage());
    }
    catch(anotherTypeOfException e) {
        //More serious, throw this one back
        throw(e);
    }
    finally
    {
    stream.close();
    }
    

    So, we can catch many types of exception, process them differently (the first allows execution for anything beyond the try{}, the second effectively returns), but always neatly and tidily clear up.

    0 讨论(0)
  • 2020-12-30 20:51

    This question is old, but this has always bothered me (I found it here for a reason). I've read every answer and it looks to me that nobody really thought it through.

    This is not an answer. I really think there is no good point to finally, which may be why it didn't exist in programming languages until "recently". Most of the examples stating stream.close() can cause null reference exceptions, so you still have to test if it's null.

    Yes, if you return from within try{}, finally still runs. But is that good practice? It seems like gynastics, might as well bring goto back. Why not wait and return after the block? All finally {} does is add two or three lines to your code.

    0 讨论(0)
  • 2020-12-30 20:54

    The finally block is in the same scope as the try/catch, so you will have access to all the variables defined inside.

    Imagine you have a file handler, this is the difference in how it would be written.

    try
    {
       StreamReader stream = new StreamReader("foo.bar");
       stream.write("foo");
    }
    catch(Exception e) { } // ignore for now
    finally
    {
       stream.close();
    }
    

    compared to

    StreamReader stream = null;
    try
    {
        stream = new StreamReader("foo.bar");
        stream.write("foo");
    } catch(Exception e) {} // ignore
    
    if (stream != null)
        stream.close();
    

    Remember though that anything inside finally isn't guaranteed to run. Imagine that you get an abort signal, windows crashes or the power is gone. Relying on finally for business critical code is bad.

    0 讨论(0)
  • 2020-12-30 20:56

    Depends on the language as there might be some slight semantic differences, but the idea is that it will execute (almost) always, even if the code in the try block threw an exception.

    In the second example, if the code in the catch block returns or quits, the x = 3 will not be executed. In the first it will.

    In the .NET platform, in some cases the execution of the finally block won't occur: Security Exceptions, Thread suspensions, Computer shut down :), etc.

    0 讨论(0)
  • 2020-12-30 21:00

    The finally block is supposed to execute whether you caught the exception or not. See Try / Catch / Finally example

    0 讨论(0)
  • 2020-12-30 21:02

    In the case, that the try and the catch are empty, there is no difference. Otherwise you can be sure, that the finally will be executed.

    If you, for example throw a new Exception in your catchblock (rethrow), than the assignment will only be executed, if it is in the finally-block.

    Normally a finally is used to clean up after yourself (close DB-connections, File-Handles and the likes).

    You should never use control-statements (return, break, continue) in a finally, as this can be a maintenance nightmare and is therefore considered bad practice

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