Is a finally block without a catch block a java anti-pattern?

前端 未结 12 632
鱼传尺愫
鱼传尺愫 2020-12-05 12:35

I just had a pretty painful troubleshooting experience in troubleshooting some code that looked like this:

try {
   doSomeStuff()
   doMore()
} finally {
            


        
相关标签:
12条回答
  • 2020-12-05 13:26
    try {
        doSomeStuff()
        doMore()
    } catch (Exception e) {
        log.error(e);
    } finally {
       doSomeOtherStuff()
    }
    

    Don't do that either... you just hid more bugs (well not exactly hid them... but made it harder to deal with them. When you catch Exception you are also catching any sort of RuntimeException (like NullPointer and ArrayIndexOutOfBounds).

    In general, catch the exceptions you have to catch (checked exceptions) and deal with the others at testing time. RuntimeExceptions are designed to be used for programmer errors - and programmer errors are things that should not happen in a properly debugged program.

    0 讨论(0)
  • 2020-12-05 13:28

    Try/Finally is a way to properly free resources. The code in the finally block should NEVER throw since it should only act on resources or state that was acquired PRIOR to entry into the try block.

    As an aside, I think log4J is almost an anti-pattern.

    IF YOU WANT TO INSPECT A RUNNING PROGRAM USE A PROPER INSPECTION TOOL (i.e. a debugger, IDE, or in an extreme sense a byte code weaver but DO NOT PUT LOGGING STATEMENTS IN EVERY FEW LINES!).

    In the two examples you present the first one looks correct. The second one includes the logger code and introduces a bug. In the second example you suppress an exception if one is thrown by the first two statements (i.e. you catch it and log it but do not rethrow. This is something I find very common in log4j usage and is a real problem of application design. Basically with your change you make the program fail in an way that would be very hard for the system to handle since you basically march onward as if you never had an exception (sorta like VB basic on error resume next construct).

    0 讨论(0)
  • 2020-12-05 13:32

    There is absolutely nothing wrong a try with a finally and no catch. Consider the following:

    InputStream in = null;
    try {
        in = new FileInputStream("file.txt");
        // Do something that causes an IOException to be thrown
    } finally {
        if (in != null) {
             try {
                 in.close();
             } catch (IOException e) {
                 // Nothing we can do.
             }
        }
    }
    

    If an exception is thrown and this code doesn't know how to deal with it then the exception should bubble up the call stack to the caller. In this case we still want to clean up the stream so I think it makes perfect sense to have a try block without a catch.

    0 讨论(0)
  • 2020-12-05 13:32

    I think that try with no catch is anti-pattern. Using try/catch to handle exceptional conditions (file IO errors, socket timeout, etc) is not an anti-pattern.

    If you're using try/finally for cleanup, consider a using block instead.

    0 讨论(0)
  • 2020-12-05 13:35

    In general, no, this is not an anti-pattern. The point of finally blocks is to make sure stuff gets cleaned up whether an exception is thrown or not. The whole point of exception handling is that, if you can't deal with it, you let it bubble up to someone who can, through the relatively clean out-of-band signaling exception handling provides. If you need to make sure stuff gets cleaned up if an exception is thrown, but can't properly handle the exception in the current scope, then this is exactly the correct thing to do. You just might want to be a little more careful about making sure your finally block doesn't throw.

    0 讨论(0)
  • 2020-12-05 13:35

    I think the real "anti-pattern" here is doing something in a finally block that can throw, not not having a catch.

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