I had a piece of code my professor commented on, saying that "this is called a squelch" and that it's a huge sin in programming.
Here's the code I had,
if (command.matches(input)) {
try {
command.execute();
} catch (UniversalException e) {
}
return;
}
The "squelch" was within the catch(). I have kind of an idea from research what this is, but if someone could explain it to me in simpler terms, I'd appreciate it. Also how to avoid a squelch would be nice, too.
Also, if it helps, that bit of code also includes
public UniversalException() {
System.out.println("The file you entered could not be located. Please try again.");
}
in another class, which is what is printed out when a user enters an invalid file name.
I don't understand any of this exception stuff well yet, and my professor simply asked for something that prints out a nice message to the user instead of a stack trace.
That's a funny, if descriptive name for it :)
If I'm not misinterpreting what your professor said, the problem is that inside your 'catch' block, you do absolutely nothing. You don't print a nice error message, you don't log the error, you don't throw the exception so that somebody else can handle it, you don't show the stack trace...
If the code inside the try block were to throw a UniversalException, your empty catch block would cause that error to be silently ignored, suppressed, or squelched.
The solution is fairly simple -- do something inside the catch block. Errors should never be silently ignored -- at minimum, you should at least print or log something so that you know something went wrong.
Now, currently, it looks like you're actually printing an error message in the constructor of the UniversalException class. I would instead move that into the catch block. An empty catch block feels sort of like a fly walking across your arm -- it just feels wrong, even if you do log the error somewhere else.
The reason why many coders have this sort of instinctual revulsion to empty catch blocks is because it usually indicates a landmine. Whenever I see an empty catch block, it usually means that the previous coder deliberately chose to ignore an error in the code and hope for the best, which is almost never the right thing to do. It's not the kind of thing that makes you optimistic about the state of the codebase.
It's also more useful to print the error message inside the catch block instead of in the constructor since you can also print out the values of local variables in the method and examine the specific exception thrown, which makes it easier to debug the problem.
Your code catches an exception (in this case, an instance of UniversalException) and does not act upon it. This way, since the exception is neither allowed to propagate "upwards" nor is it handled in any way, you are effectively hiding the fact that it ever occurred.
Related
There is a legacy Java project.
During the code review, I have noticed that my colleagues replaced the code
} catch (Exception e) {
ok = false;
}
// and ok was never used since then
with
} catch (Exception e) {
e.printStackTrace();
}
That is, the worst practice "ignore the exception" was replaced by the second worst "print the exception to stdout and go on". (The colleagues believe that the code does not get worse because of that.)
I know that there is a whole holy war about it, and that really clever people advice everyone to first of all think before catching exceptions. Unfortunately, it looks like this already has not been done. The legacy code catches exceptions and ignores them. It is possible to modify the code to throw an exception instead of ignoring it, but nobody knows how many use case scenarios will break because of that. Unit tests do not help because the method is not covered by unit tests. Nobody even knows in how many scenarios the method gets called.
Given that the contract between the caller and the called method is not clear, what can we do with legacy code that catches and ignores exceptions?
There are cases where Exceptions are expected and it is safe to go on. In any case you should use a logger framework to log exceptions rather than
e.printStackTrace();
So first you should transform this into
logger.error("context", e);
Some options:
Use logs to detect which Exceptions are okay, and demote them to logger.info() or logger.debug() (as commented by #Ivan)
after some time, change the remaining locations to throw a new checked exception. This will allow you to get compiler feedback about which other code will be impacted. Later you can revert to unchecked.
start unit testing
start protecting the main loop / entry points of your product from unchecked exceptions happening anywhere
I am a fresher, and after successfully completing my project I scanned it through fortify. it gave me a list of issues, out of which just one categories remain. (Fortify a code quality scanning tool)
it says, "Not to use Broader Exception i.e. System.Exception" to catch exceptions unless in some conditions.
But I have a few methods that have 25-30 lines of code with different types of operations, in such case how to figure out which all specific exceptions to catch.
Should we also throw all these exceptions to be caught at a higher level catch, as i read "throw first catch late".
Please suggest me a clean way to do this.
e.g.
public SomeMethod(arg) throws IOException,SQLException,beanNotFoundException {
try {
someCode
} catch (IOException|SQLException|beanNotFoundException ex) {
logger.log(ex);
throw ex;
}
}
But also if i don't use Exception Class altogether till the end, i also have to make sure that I am not missing any exception to handle.
Is there a better approach.
Static Analysis
First and foremost, let me start with a little fallacy that most people fall subject to (and I see a lot in the corporate world): Static analysis tools are not infallible. They make mistakes. There are some warning classes that, with all the computing power known to man and with the remaining lifespan of the universe, the tool may not be able to exhaustively analyze a piece of code related to a particular warning class. Moreover, there are some warning classes that can complete before the end of time, but would be unreasonable to expect you to wait 7 days for an answer for one warning on one section of code for one execution path. That is, static analysis tools have to make guesses sometimes. The better tools are better at making guesses (you pay for what you get), but in the end, they are all capable of guessing right (true positive/negative) or wrong (false positive/negative).
Additionally, some warning classes may be applicable and some may not be. Some other warning classes may be important to you and some may not be. For example, PMD has a warning class to the effect of "Unused Import". An unused import has no effect on runtime, and while it may not be ideal, you can leave it in your code and it will not affect you unless your codebase is large and requires time to compile, and you have lots of these (unused imports make it longer to build your project). I particularly mention static analysis, because it sounds like you ran Fortify on your codebase and fixed anything and everything without questioning the validity. Most of the time it will probably be right, but just don't take it as fact because it told you so. You need to question whether these tools are always right.
Your example
So your example is not a false positive. If you do
throw new Exception("");
that's generally not what you want to do. It's fine for debugging and just quickly throwing code together. But, as your codebase gets larger, handling Exceptions will get more difficult.
This leads me right into my next point. You make the statement
But I have a few methods that have 25-30 lines of code with different types of operations, in such case how to figure out which all specific exceptions to catch.
...
But also if i don't use Exception Class altogether till the end, i also have to make sure that I am not missing any exception to handle.
Which seems to indicate to me that you either have something to the effect of
try{
//25-30 lines of code
} catch (Exception ex) { /*ex.printStackTrace(); Logger.getLogger(...).log(...); etc etc...whatever it is you do here, or maybe nothing at all*/
This is pretty bad - in most cases.
To get back to answering your question before I explain why, yes, you should absolutely catch each individual exception. The reason for this, and why your catch all is bad, is because if there is something specific that goes wrong, you can't have a specific type of error handling.
For example, take a function Foo#bar(java.lang.String), which throws an IOException when a disk access fails because you tried to write to a bad file, a BooException if you pass in a String without a special character in it, or a BazException for some other arbitrary reason. Now let's go back to your example from above: what if I wanted to realize that the file I was writing to was bad, and maybe prompt the user for some clarification before I moved on? What if I knew that if a BooException was thrown, that the user should have never been here in the first place, and I need to redirect them to some location? What if I knew that when a BazException that the system was out of sync with some other system and that this is a fatal problem, and now I need to do resource cleanup before I forcefully crash the JVM?
The above reasons are why you should do individual try/catch blocks for each statement and each exception.
That being said, there are reasons to not do this. Imagine, with the above example, that all you want to do for a IOException, BooException and BazException (and also any runtime exceptions, i.e. NullPointerException) that I just want to log the exception and move on. In this case, I would say it's OK to do a try/catch around a block of code - so long as it's just around the code that this applies to.
EDIT: You made a point about missing an exception, but putting a response to that in the comments seemed unruly to look at. In any case, let me start off by saying if it is not a runtime exception, then you will not even be able to compile without handling it. Catching Exception catches everything, runtime or not, which is how you compile now. From my example above, if there are runtime exceptions you are worried about missing, instead of just starting off with catching Exception:
Foo myFooInstance = new Foo();
String someValue = "value";
try {
myFooInstance.bar(someValue);
} catch (IOException ioe) {
/*handle file access problem*/
} catch (BooException boe) {
/*handle user in wrong spot*/
} catch (BazException bze) {
/*handle out-of-sync fatal error*/
} catch (Exception ex) {
LogRecord lr = new LogRecord(Level.SEVERE, "Unhandled exception!! returning immediately!!");
lr.setThrown(ex);
lr.setParameters(new Object[]{someValue});
Logger.getLogger(MyClass.class.getName()).log(lr);
return;
}
Here you end with your catch-all rather than starting with it. Think of it as your last-ditch effort to try to handle everything. It may not mean the exception is fatal to your program, but you probably shouldn't continue either (hence why my example uses return;)
Another small thing to consider, is that it becomes exponentially more difficult for the JVM to catch the exception properly the larger the try block gets (if the exception is never thrown, there is no overhead). This is more trivial to powerful machines, but something to keep in mind. With that in mind, I also don't have any sources for performance about exceptions being thrown in large try blocks, so take that with a grain of salt unless somebody finds something and mentions it.
In general, you only need to worry about handling/throwing checked exceptions. A clean way to write the method depends on the code base and structure of your application. Here are some alternatives:
If you want the client code (code calling someMethod) to handle the exception, you can do this:
public void someMethod(String arg) throws IOException, SQLException,
BeanNotFoundException {
doSomething(arg);
}
If you can handle the exception locally in someMethod, do so, but do not rethrow the same exception up in the call stack:
public void someMethod(String arg) {
try {
doSomething(arg);
} catch (IOException | SQLException | BeanNotFoundException ex) {
logger.log(ex);
handleException(ex);
}
}
If the exception is something you cannot recover from, and you don't want to enforce client code to handle the exception, you can wrap it as a RuntimeException. This will potentially terminate the program (which is usually what you want when a fatal error occurs):
public void someMethod(String arg) {
try {
doSomething(arg);
} catch (IOException | SQLException | BeanNotFoundException ex) {
logger.log(ex);
throw new RuntimeException(ex);
}
}
For a good explanation about checked vs. unchecked exceptions, you can refer to Java: checked vs unchecked exception explanation.
My advice would be to ignore what Fortify is saying. Or better still, figure out how to selectively suppress these warnings.
The alternative to your current version that Fortify is suggesting is objectively bad in most contexts. Your current version is not bad, only (a bit) verbose.
Another alternative would be to wrap the exceptions in a custom exception or exceptions that have a common custom checked exception as the base-class (NOT Exception or Throwable or RuntimeException). That could make code like you example neater, but it means that you need to add code (somewhere) to do the wrapping and (maybe) unwrapping. In short, that's no idea too.
OK so what is the problem with catching Exception? Well basically, it catches everything ... including any unexpected uncheck exceptions that are evidence of bugs. If you then declare the method as throws Exception it only gets worse.
I have seen an example (no names) where someone did this in a large Java product. The result is that the product's Java APIs are horrible to program against. Every non-trivial API method is declared as throws Exception, so someone programming against the APIs has no idea what to expect. And the code-base is proprietary and obfuscated. (And the worst thing is that the lead developer still thinks it was a good idea!)
What about wrapping the exceptions in RuntimeException? That's not quite as bad1 as Exception but the problem is that the programmer still can't tell what exceptions to expect.
1 - It is not quite as bad in the sense that throws Exception is effectively "noise" once you have gone done the path that anything can throw anything.
The general rule of thumb is that checked exceptions are thrown for errors that are external or unpredictable, and which the caller can reasonably be expected to do something about, even if that only means displaying a message to the user. Whether you catch them or pass them up the call stack depends on where it makes the most sense to handle them.
Unchecked exceptions are thrown for unsatisfied preconditions or invalid arguments. In other words, the programmer screwed up. That's why you're not forced to catch them; they're typically things that "shouldn't happen." You generally don't need to worry about them if you're using the API correctly. The only time you should catch unchecked exceptions is when an API doesn't follow these conventions and throws unchecked exceptions for external or unpredictable reasons.
Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 8 years ago.
Improve this question
I have been coding in Java for work but everything I know about Java comes from googling how to do anything whenever I need to know. I have done C/C++ at school before and now I'm just getting into exception handling in Java.
In Java, why should we specify the exception type in the catch block? What are some advantages to doing so? What are some disadvantages to just using Exception instead of, say "IOException"?
Also when should I use the try/catch block when coding? I noticed that I got into the pattern of just coding the logic part, and I only add try/catch if an error shows while coding telling me to add it, or when I run the code and the program quits halfway because of an exception, then I find where it happens in the code and add the try/catch block there to "handle the exception" in order to get the code keep running. Is this how people normally decide where to add in try/catch? Is there a more efficient way such as "when doing certain things in code, add try/catch"?
Thanks a lot!
EDIT:
When should I use try/catch blocks and when should I use private void method() throws Exception? What's the difference between the two besides the syntax?
A lot of relatively new programmers have this thought that all exceptions are bad, but this isn't true. Exceptions are neither good or bad. They just provide information.
Take NullPointerExceptions vs FileNotFoundExceptions.
Generally (not always), if a NullPointerException is thrown, it means that there was a bug in your code somewhere. You forgot to initialize a variable, didnt check to see if a flag was true, etc. When these exceptions are thrown, you generally want your program to fail and crash, because it encountered unexpected behavior. You want the failure to be loud and obvious, because if the program didn't fail immediately after a null pointer, the program might get really wacky, and you would have a hard time finding the problem.
However, FileNotFoundExceptions are generally the opposite.
Imagine if at some point in your program, you prompted the user for a file. The user may or may not input a valid file, but the program shouldn't crash here either way. Instead, the user should be notified if the file can't be found, and prompted again. This is generally why you have catch blocks, so if that exception gets thrown, you can handle it and continue (by displaying your dialog/message/whatever).
However, if a NullPointerException was thrown here, you would definetly want your program to crash (as it's probably a bug in your code). This is why catch blocks force you to specify the Exception, so you can deal with some (such as FileNotFoundException), and let others through (such as NullPointerException)
Generally, you want to catch exceptions if your program is capable of recovering from that exception. This is (supposed to be) why java forces you to try/catch certain exceptions. Most of those exceptions are meant to be exceptions your program should be able to recover from (although sometimes, you would want to fail instead, either by declaring that your method throws that exception, or wrapping the caught exception in a RuntimeException).
I might be leaving out details I am unfamiliar with myself. But as far as I know specifying the specific exception type, allows you to get more detailed info on the error in the log.
Also eclipse and other ide's usually show a warning when it's "proper" to use try/catch blocks.
Hope it answers the question to some extent
The point of specifying which exceptions to catch is fairly straight forward. The main thing to remember is that Exceptions are classes, and have an inheritence hierarchy. For example, IOException inherits from Exception. This allows you to catch different exceptions, and handle them in different ways.
try {
....
} catch (IOException e){
logger.fatal("An IO Exception occurred.");
} catch (NullPointerException e){
logger.info("A null pointer exception occurred.");
}
In the above example, an IO exception will be logged as fatal, but a null pointer is only logged at the info level. Any exceptions that may be thrown besides these two will not be caught, and will be thrown to the next level of error handling. This could either crash your program, or a method higher up the call chain may handle the thrown exception.
try {
....
} catch (IOException e){
logger.fatal("An IO Exception occurred.");
} catch (NullPointerException e){
logger.info("A null pointer exception occurred.");
} catch (Exception e) {
logger.fatal("An unexpected exception occurred.");
}
In this second example, all exceptions are caught. Only one catch block will be executed though (The first one that matches).
A good way to plan when writing code is to:
1) Determine if this line of code can fail. (IO, parsing text, calling a service...).
2) If this code fails, do I want to handle this failure here (with a catch block) or later, by throwing the exception up the call chain.
You should specify the type of the exception in most cases because methods you call may throw different types of exceptions. For example, let's say you're trying to access a file in the file system, when you call the method to do this, the method can throw a FileNotFoundException which as the name describes, you will get when the file path you gave it does not exist. The method could also throw an IOException if the file does exist, but there's some other problem with the IO device or the file itself.
Usually, you would want to know the difference between these two errors and act accordingly, in which case you will have to put two catches, one for FileNotFoundException and another for IOException.
If for some reason you don't care about the specific error, then you simply put one catch for a regular Exception.
For the answers to your other questions, you can find them here http://docs.oracle.com/javase/tutorial/essential/exceptions/index.html
so my professor has assigned us a project where we have to take in commands from a text file and use them to drive the flow of our program. These commands such as- Takeoff, land, load cargo, unload cargo, etc.- are meant to simulate an airplane-like object.
Sometimes these commands don't make sense to execute, like loading cargo while a plane is in-flight. Therefore, to prevent something like that from happening we had to code in our own exception classes i.e. "If the plane is ordered to load cargo while in flight, throw InvalidActionException"
My question is: how can I continue to read-in commands from the text file after exceptions have been thrown (seeing as how once they are thrown, the program cannot progress further
Here's an outline of what I want to do:
Scanner input = new Scanner(new FileInputStream("stuff1.txt"));
while(input.hasNextLine())
{
try
{
//execute commands by reading them using input.nextLine()
}
catch()
{
//catch any exceptions and ignore them... continue to read
//the file for more commands
}
}
I would appreciate any help. Thanks.
Catch appropriate exception and flow will automatically reach while loop condition.
After cathing exception nothing extra to be done to continue the program.
seeing as how once they are thrown, the program ends abruptly
Only uncaught exception stop a thread. I suggest you catch all the exceptions you want to continue after and you won't have a problem.
Catch your specific exception:
while(input.hasNextLine())
{
try
{
//execute commands by reading them using input.nextLine()
}
catch ( UserDefinedException ex )
{
//catch the exceptions you're throwing
}
}
That's exactly what you want to do. All the reading and processing statements go in the try block, and the catch block just contains error processing (which may consist of nothing other than printing a warning message somewhere.
The thing you need to be careful of is that you don't get stuck in an endless loop. Make sure each time around the loop you're processing new data!
Since your catch is inside the while loop, the loop will naturally continue onto the next iteration after the exception has been caught.
Any exception caught in your catch block(s) will not cause the program to terminate. Simply catch the Exception(s) you want handled and your loop will continue.
while(input.hasNextLine())
try {
//execute commands by reading them using input.nextLine()
}
catch (CargoLoadingException e)
{
System.err.println("Can't load cargo while the plane is in flight.");
}
catch (OtherException e)
{
e.printStackTrace();
}
}
Note that if you catch Throwable, you basically catch any exception that can be thrown. However, you probably only want to catch specific exceptions. For example, PlaneCrashException probably should cause the program to terminate.
The outline you have shown is sufficient to achieve what you want (i.e. the try-catch-construct is inside the while loop). Just make sure that the catch statement declares the correct type or supertype of exception you want to catch-and-ignore.
UPDATE: If you are unsure about what kind of exception to catch, you might want to catch "Throwable", but this is not really recommended. When your teacher had you implement your own exceptions, you probably based them off one existing Exception class. You might want to catch that Exception type then.
And on a totally differnt note, you might want to read in the entirety of the commands from the text file into a list of strings before executing the sequence. This might save you from some IO problems, because you keep the file handle open all the time (which seems unnecessary for such a straight-forward task).
To add to the other answers: Exceptions can do a number of jobs. All too commonly, they tell you that your program is hopelessly unstable and should shut down immediately.
Normally, they tell you that something bad and unexpected happened, and give you a chance to explain the problem to the user and then carry on. For instance, an unexpected End-Of-File exception. You can tell the user the file is bad and let them try another one. You can also print out a stack trace so they can call you and you can figure out what happened even if you did not print an extensive error message.
Note the split personality of this exception. Like the first type (RunTimeException instances, usually), they let you know exactly what happened almost without you doing anything. However, Java also forced you to be aware that an IOException could be thrown and tried to force you to write a nice message for the user. I've always been a bit puzzled about this. If I catch an EOFException, I know where it happened and I don't need the stack trace. (Of course, if I know an EOF cannot happen, I'm not going to bother with a proper message to the user, and the stack trace when it does happen will be very handy.)
But there's a third sort of an exception, sort of the second personality of the previous exception. It just lets you know something perfectly normal happened. It is highly efficient (if you set it up right; see below). And it can be a lot cleaner than returning values up a stack of method calls. It allows a method that already returns, say, a String (with a null reference being perfectly okay) to alert the calling method to a special condition and, optionally, provide vast amounts of data on that condition.
public static class MyEOFException extends EOFException {
// Saves creating a meaningless stack trace.
public Throwable fillInStackTrace() { return this; }
}
// Saves creating a new object every time you use it
public static MyEOFException myEOF = new MyEOFException();
Then, inside a method:
try {
for (;;) {
String text = readAStringFromFile( in );
// Do something with text...
}
}
catch (MyEOFException e) {
// Nothing at all needs to be done here.
// Note that MyEOFException COULD have beeen set up with tons of data and
// then a lot of work could be done. (The file might end with binary
// data, for instance, which would be in "e".)
}
The exception could be thrown many levels down and it will pop you out of the loop quite neatly. In most such cases, this would be a little too simplistic. Often it's too complicated; try-catch blocks can be annoying. Something like:
while (readAStringFromFile( in ));
is a lot nicer and faster to write if readAStringFromFile has a place to put what it read.
In your particular case, using exeptions like this may be what your professor is looking for. My personal experience is that there is almost always a better way to do it than with try-catch blocks, but when they do work they work really well.
There are 3 permutations of a try...catch...finally block in java.
try...catch
try...catch...finally
try...finally
Once the finally block is executed, control goes to the next line after the finally block. If I remove the finally block and move all its statements to the line after the try...catch block, would that have the same effect as having them in the finally block?
I know this is a very old question but I came across today and I was confused by the answers given. I mean, they are all correct but all answer on a theoretical or even philosophical level when there is a very straightforward practical answer to this question.
If you put a return, break, continue or any other java keyword that changes the sequential execution of code inside the catch block (or even try block), the statements inside the finally block will still be executed.
For example:
public void myFunc() {
double p = 1.0D;
String str = "bla";
try{
p = Double.valueOf(str);
}
catch(Exception ex){
System.out.println("Exception Happened");
return; //return statement here!!!
}finally{
System.out.println("Finally");
}
System.out.println("After finally");
}
when executed this code will print:
Exception Happened
Finally
That is the most important reason for the existence of a finally block. Most answers imply it or refer to it on the sidelines but none of them is putting emphasis on it. I think because this is kind of a newbie question such a straightforward answer is very important.
I think willcode comes the closest to expressing the key point here, and probably everyone means it but are not clear.
The problem is there is indeed something very wrong with what you are asking: "If i write all the statements after catch block instead of writing them into finally block then then would there be anything wrong?"
If you write all the statements after the catch block, what you are implying is that
1) You will always catch the exception.
2) You will always continue on to the next statements after you catch the exception.
This implies that you will always continue the execution "normally" after an exception, which is generally something you never in fact want to do.
Exceptions should be just that - exceptional. If you can in fact handle an exception, it is always better to write your code to consider those conditions first and not lead to an exception at all. If you follow this model then exceptions are truly exceptional - conditions you could not anticipate or at most not fix. Really not anticipate is what you should work towards. This means in general you are unable to handle true exceptions, which also means you should not just continue execution, often you end the application instead.
What is normally done is you allow an error to propagate back up the call stack. Some say this is done on the off chance that someone higher up in the chain may be able to handle it. I would say that essentially never happens, there are two real purposes to do this. One it may be something the user can fix, if there is one. So you propagate the error back up until you get to where you can report it to the user. Or two, a user cannot fix it but you want to get the entire call stack for debugging. Then you catch it at the top to fail gracefully.
The finally block now should have more meaning to you. As everyone says it always runs. The clearest use of a finally is really in a try... finally block. What you are now saying is if the code runs fine, great. We still need to do some clean up and the finally always executes then we move on. But if an exception occurs, we now really need that finally block because we may still need to do some clean up, but we are no longer catching the exception here so we are not going to be moving on anymore. The finally block is essential to ensure that clean up occurs.
The idea of an exception always halting execution may be hard for someone to grasp until they have a certain amount of experience, but that is in fact the way to always do things. If an error happened, either it was so minor you should have accounted for it to begin with, or else there are just more and more errors waiting to happen down the line.
"Swallowing" errors - catching them and moving on is the worst thing you can do because your program becomes unpredictable and you cannot find and fix bugs.
Well written code will contain as many try ... finally blocks as are necessary to make sure that resources are always released no matter the outcome. But well written code generally contain only a small number of try ... catch blocks that exist primarily to allow an application to fail as gracefully as possible, or defer to the user, which means at least always pass a message to the user etc. But you usually do not just catch an error and keep going.
The highlight is that a finally block is guaranteed to be executed even if an exception is raised and not caught. You then use the finally block, as a one time chance, to perform necessary clean-up like closing streams. The code after the finally block might never be reached.
From the java tutorial
The finally block always executes when
the try block exits. This ensures that
the finally block is executed even if
an unexpected exception occurs. But
finally is useful for more than just
exception handling — it allows the
programmer to avoid having cleanup
code accidentally bypassed by a
return, continue, or break. Putting
cleanup code in a finally block is
always a good practice, even when no
exceptions are anticipated.
If I understand the question, you're asking what's the difference between:
try {
Foo f = new Foo();
f.bar();
}
finally
{
Foo.baz();
}
And:
// This doesn't actually compile because a try block needs a catch and/or finally block
try {
Foo f = new Foo();
f.bar();
}
Foo.baz();
Or, more likely:
Foo f = new Foo();
f.bar();
Foo.baz();
The difference is that if either new Foo() or f.bar() throw an exception, the finally block will get executed in the first case, but that Foo.baz() won't get executed in the last two cases: instead control will skip over Foo.baz() while the JVM looks for an exception handler.
EDIT
Responding to your comment, what about:
Foo f = new Foo();
try {
f.bar();
}
catch (Exception ex)
{
// ...
}
f.baz();
You are right that, assuming the catch block doesn't rethrow the exception, or return from the method indicating a failure occured, then f.baz() gets called regardless of whether there was an exception. Even in that case, however, the finally block serves as documentation that f.baz() is used for cleanup.
More importantly, the fact that an exception was thrown usually is important, so it's very hard to write code that continues on doing whatever it was doing without knowing that an exception was thrown. There are times that exceptions indicate silly things that you can ignore, and in that case you should swallow the exception. More often, however, you will want to signal failure, either by rethrowing the exception (or throwing a different exception) or returning from the method with an error code.
For example, if f.bar() is supposed to convert a String to a Double, and on failure it throws a NumberFormatException, then code after the try block probably needs to know that the String was not actually converted to a Double. And, so, in general you won't want to continue after the catch block. Instead, you'll want to signal failure. This is known as "abort on failure" (compared to "resume on failure," which probably should be called "muddle on after failure with your fingers crossed").
Except, in special cases you may be able to muddle on. For instance, the catch block could set the relevant Double to Double.NaN which is designed specifically to propagate errors correctly in math expressions. Even in that case, the finally block serves as documentation that f.baz() is involved in some kind of cleanup.
The finally block contains lines of code that should be executed regardless whether an exception has been caught or not. Even if you decide to stop code running in that method. So code after the t-c-f might not be executed, but the finally code is "guaranteed" (guaranteed in the sense of a non crashing immediately breaking non handleable error).
Yes, there would be something very critically wrong.
And that is, your code would only run if there is an error.
Statements inside finally always run, regardless of an exception being thrown. That is the point.
finally block especially used at the time of exception prevention. If any runtime error occurs, the program may lead to terminate. So at this time, it will call finally block before going to terminate the program. Usually 'finally' contains connection closing statements, save operations and file input, output close operations.
If your code never throws exception, or you are consuming all exception that will be correct. That is not what always happens.
The question was indeed answered here (how to use finally)
My understanding of the answer is: there would be circumstances in which we would throw some exception that the except block won't be able to handle. What do you do in that situation? You wanna move on? Not a great idea! You better print something that indicates that you passed through a stage where an exception may or may not have occurred, if the exception occurred it should have been handled by the catch statement and if it was not handled, there may be some unmatched exception