CATEGORII DOCUMENTE |
Asp | Autocad | C | Dot net | Excel | Fox pro | Html | Java |
Linux | Mathcad | Photoshop | Php | Sql | Visual studio | Windows | Xml |
There's often some piece of code that you want to execute whether or not an exception occurs in a try block. This usually pertains to some operation other than memory recovery (since that's taken care of by the garbage collector). To achieve this effect, you use a finally clause at the end of all the exception handlers. The full picture of an exception-handling section is thus:
try catch (A a1) catch (B b1) catch (C c1) finally
To demonstrate that the finally clause always runs, try this program:
//: FinallyWorks.java
// The finally clause is always executed
public class FinallyWorks catch(Exception e) finally
}
}
} ///:~
This program also gives a hint for how you can deal with the fact that exceptions in Java (like exceptions in C++) do not allow you to resume back to where the exception was thrown, as discussed earlier. If you place your try block in a loop, you can establish a condition that must be met before you continue the program. You can also add a static counter or some other device to allow the loop to try several different approaches before giving up. This way you can build a greater level of robustness into your programs.
The output is:
Exception thrown
in finally clause
No exception
in finally clause
Whether an exception is thrown or not, the finally clause is always executed.
In a language without garbage collection and without automatic destructor calls, finally is important because it allows the programmer to guarantee the release of memory regardless of what happens in the try block. But Java has garbage collection, so releasing memory is virtually never a problem. Also, it has no destructors to call. So when do you need to use finally in Java?
finally is necessary when you need to set something other than memory back to its original state. This is usually something like an open file or network connection, something you've drawn on the screen or even a switch in the outside world, as modeled in the following example:
//: OnOffSwitch.java
// Why use finally?
class Switch
void on()
void off()
}
public class OnOffSwitch catch(NullPointerException e) catch(IllegalArgumentException e)
}
} ///:~
The goal here is to make sure that the switch is off when main( ) is completed, so sw.off( ) is placed at the end of the try block and at the end of each exception handler. But it's possible that an exception could be thrown that isn't caught here, so sw.off( ) would be missed. However, with finally you can place the closure code from a try block in just one place:
//: WithFinally.java
// Finally Guarantees cleanup
class Switch2
void on()
void off()
}
public class WithFinally catch(NullPointerException e) catch(IllegalArgumentException e) finally
}
} ///:~
Here the sw.off( ) has been moved to just one place, where it's guaranteed to run no matter what happens.
Even in cases in which the exception is not caught in the current set of catch clauses, finally will be executed before the exception-handling mechanism continues its search for a handler at the next higher level:
//: AlwaysFinally.java
// Finally is always executed
class Ex extends Exception
public class AlwaysFinally finally
} catch(Ex e) finally
}
} ///:~
The output for this program shows you what happens:
Entering first try block
Entering second try block
finally in 2nd try block
Caught Ex in first try block
finally in 1st try block
The finally statement will also be executed in situations in which break and continue statements are involved. Note that, along with the labeled break and labeled continue, finally eliminates the need for a goto statement in Java.
In general, Java's exception implementation is quite outstanding, but unfortunately there's a flaw. Although exceptions are an indication of a crisis in your program and should never be ignored, it's possible for an exception to simply be lost. This happens with a particular configuration using a finally clause:
//: LostMessage.java
// How an exception can be lost
class VeryImportantException extends Exception
}
class HoHumException extends Exception
}
public class LostMessage
void dispose() throws HoHumException
public static void main(String[] args)
throws Exception finally
}
} ///:~
The output is:
A trivial exception
at LostMessage.dispose(LostMessage.java:21)
at LostMessage.main(LostMessage.java:29)
You can see that there's no evidence of the VeryImportantException, which is simply replaced by the HoHumException in the finally clause. This is a rather serious pitfall, since it means that an exception can be completely lost, and in a far more subtle and difficult-to-detect fashion than the example above. In contrast, C++ treats the situation in which a second exception is thrown before the first one is handled as a dire programming error. Perhaps a future version of Java will repair the problem. (The above results were produced with Java 1.1.)
C++ exception handling does not have the finally clause because it relies on destructors to accomplish this sort of cleanup.
A destructor is a function that's always
called when an object becomes unused. You always know exactly where and when
the destructor gets called. C++ has automatic destructor calls, but & and
2 do not (which changes the meaning and use of the concept of a
destructor for that language).
Politica de confidentialitate | Termeni si conditii de utilizare |
Vizualizari: 700
Importanta:
Termeni si conditii de utilizare | Contact
© SCRIGROUP 2024 . All rights reserved