Java Exception Handling - Style

后端 未结 8 1640
别跟我提以往
别跟我提以往 2021-01-17 15:42

Historically I have always written my Exception handling code like this:

    Cursor cursor = null;
    try {
        cursor = db.openCursor(null, null);
             


        
相关标签:
8条回答
  • 2021-01-17 16:35

    I always do mine the second way, because it allows for me to set cursor as final. There's no reason I can see to have the assignment in the try clause if you are not actually trying to catch exceptions from it.

    EDIT: Just to note, from the further discussion that has gone on. This is how I would handle the openCursor call throwing an exception:

    try
    {
        // ALLOCATE RESOURCE
        final Cursor cursor = db.openCursor(null, null);
    
        try
        {
            // USE RESOURCE
        }
        finally
        {
            // DISPOSE RESOURCE
            cursor.close();
        }
    }
    catch(OpenCursorException e)
    {
        // Handle this appropriately.
    }
    

    Note the clean separation of allocation, usage, and disposal. The only time this gets a little interesting is if the usage try block throws the same exception that you're catching for the allocation try block. (IOException would be a particularly good example of this, as opening and reading can both throw one.) In that case, everything will still clean and dispose correctly, but you might incorrectly attribute failure to an initialization exception instead of a usage exception. In this case, you will want to catch the exception(s) in the inner try block and handle them immediately in there.

    0 讨论(0)
  • 2021-01-17 16:37

    If all you are doing in your finally is closing the cursor then the second form is correct. You will never have a cursor to close if openCursor() fails. The value of that variable won't even have been set.

    As others allude to, the caveats are if you are doing additional initialization that requires its own clean up then that will logically have to go in the finally{} and change the scope accordingly. Though I'd argue for a restructuring in that case.

    The bottom line: as written the first version is needlessly complicated. The second version is correct.

    Edit: Incorporating my other comments for posterity...

    The first example might seem harmless as all it does is add a bunch of needless code. (Completely needless, if that wasn't clear.) However, in classic "more code means more potential bugs" fashion, there is a hidden gotcha.

    If for some reason the "// do something" code inadvertently clears the cursor variable then you will silently leak cursors whereas before you'd at least have gotten a NullPointerException. Since the extra code does absolutely nothing useful, the extra risk is completely unnecessary.

    As such, I'm willing to call the first example "just plain wrong". I'd certainly flag it in a code review.

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