Do you really need the 'finally' block - java

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

Related

how exception finds correct catch block

I was wondering how catch block works.
I have below code,
catch(ArithmeticException e){
System.out.println("task1 is completed");
}
catch(ArrayIndexOutOfBoundsException e){
System.out.println("task 2 completed");
}
catch(Exception e){
System.out.println("common task completed");
}
If divide by zero occurs it will go to Arithmetic Exception and skips rest.
How is it internally implemented so that it is going into the correct catch block?
If by "implemented" you mean "what is the bytecode generated for this", that part is of course covered by the language specification, and there is a good article about it.
Basically, every code segment (method) can have an associated exception table. In this table, you have an entry for every catch block, that specifies which lines of code are covered by it (the extent of the try block), what exception is being caught, and where to jump to handle it (the catch block).
When an exception is raised, the JVM goes through this table from top to bottom and continues execution in the first catch block that matches.
If it does not find one, it exits the current method and looks in the exception table of the caller (the exception bubbles up the call stack until someone deals with it).
It does not directly go to the matching catch block...
But it linearly searches each catch block to find the required exception, if it finds then it skips rest of the catch block... Thats All.
The first matching catch block is executed.
For more details see here: https://docs.oracle.com/javase/tutorial/essential/exceptions/catch.html
Its not much of going to a specific block. In your try block an exception can and normally is "thrown" your catch block merely anticipates the exception and "catches" it preventing the program from crashing.
` Java has a built-in mechanism for handling runtime errors, referred to as exception handling. This is to ensure that you can write robust programs for mission-critical applications.
Older programming languages such as C have some drawbacks in exception handing. For example, suppose the programmer wishes to open a file for processing:
1.The programmers are not made to aware of the exceptional conditions. For example, the file to be opened may not necessarily exist. The programmer therefore did not write codes to test whether the file exists before opening the file.
2.Suppose the programmer is aware of the exceptional conditions, he/she might decide to finish the main logic first, and write the exception handling codes later – this "later", unfortunately, usually never happens. In other words, you are not force to write the exception handling codes together with the main logic.
3.Suppose the programmer decided to write the exception handling codes, the exception handling codes intertwine with the main logic in many if-else statements. This makes main logic hard to follow and the entire program hard to read. For example,
if (file exists)
{
open file;
while (there is more records to be processed) {
if (no IO errors) {
process the file record
} else {
handle the errors
}
}
if (file is opened) close the file;
} else {``
report the file does not exist;
}
`

What can happen if I catch an error?

Surprisingly google didn't describe any catastrophic scenarios my twisted mind craved for.
Anywhere I read, catching errors is discouraged. Basic rule seems to be that if your application produced error, it's already dead, beyond saving. So if you catch errors in your main function, does your program turn into zombie?
How can even error be caught if the program is already collapsing? Can catching errors do something real bad? Which errors are worst and which are sometimes caught? Could you describe a little test case that can produce the errors (like really produce them, not just throw them) so that I can see that they do if I catch them and ignore them?
Not much happens except that the thrown object is caught. Your process can be in a bad place, though, depending on what caused the error.
A StackOverflowError is pretty undramatic to catch - it's thrown when the maximum stack depth is exceeded, and since it then starts popping the call stack, it's no longer a problem (unless you try calling the offending method again).
class SO {
static int stackOverflow(){ return stackOverflow(); }
public static void main(String... args) {
try {
stackOverflow();
} catch (StackOverflowError e) {
System.out.println("Oh well, life goes on.");
}
}
}
Other errors, like OutOfMemoryError, are somewhat more problematic - there will still be too much memory used after it's been thrown. Some are directly fatal, like ClassFormatError, which means that you're trying to load a broken class file (and it's usually thrown in places where you can't catch it).
Other Errors are somewhere inbetween. AssertionError, for example, is thrown when a programmer-defined condition (like assert answer == 42;) isn't met, but only if you've enabled assertions.
Long story short, though: If you're catching specific errors, you're probably doing the wrong thing (unless you really know what you're doing!). If you're running a server app and want it to keep running, you're probably better of letting the current thread or process die and have it restarted by some kind of monitor.
Catching an Exception or Error is not a good idea, unless;
you can do something useful with it.
as a last resort to ensure it is logged correctly or in a submitted Runnable to an ExecutorService. In this case catching Throwable may be desirable.
Nothing terrible will happen if you catch an Error, however you can't pretend it didn't happen either (i.e. you can't just continue as if it didn't matter)
Note: not catching an error can be a bad thing for multi-threaded applications. This is because an uncaught error only closes the current thread. If there are multiple threads, they will keep running if at least one is not a daemon This can leave a program running but in a bad state.
I ask what happens.
Nothing special, you catch it and you can deal with it or log it.
Are you talking about catching Exceptions? There are two types of Exceptions checked and unchecked. The reason to catch an Exception as simple as catching a programmer defined Exception which enables the user to reenter the data. This normally applies to checked Exceptions.
Unchecked Exceptions cannot be recovered from and you might ask why catch them at all? Perhaps the developer wants to catch it to log the conditions which caused the Exception and to better troubleshoot the issue.
Here is an article discussing them both.
http://tutorials.jenkov.com/java-exception-handling/checked-or-unchecked-exceptions.html

What is a squelch in java?

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.

Java: How to continue reading a file after an exception is thrown

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.

Java try/catch performance, is it recommended to keep what is inside the try clause to a minimum?

Considering you have code like this:
doSomething() // this method may throw a checked a exception
//do some assignements calculations
doAnotherThing() //this method may also throw the same type of checked exception
//more calls to methods and calculations, all throwing the same kind of exceptions.
Now I know, there is in fact a performance hit when constructing the exception, specifically unwinding the stack. And I have also read several articles pointing to a slight performance hit when entering try/catch blocks, but none of the articles seem to conclude anything.
My question is, is it recommended to keep the lines inside the try catch to bare minimum?, i.e. ONLY have inside the try clause the lines that can actually throw the exception you are catching. Does the code inside the try clause run slower or cause any performance hit?.
But more important what it is the best practice/more readable solution considering doing this:
try {
doSomething() // this method may throw a checked a exception
//do some assignements calculations
doAnotherThing() //this method may also throw the same type of checked exception
//more calls to methods and calculations, all throwing the same kind of exceptions.
}
catch (MyCheckedException e) {
//handle it
}
or :
try {
doSomething() // this method may throw a checked a exception
}
catch (MyCheckedException e) {
//Store my exception in a Map (this is all running in a loop and I want it to continue running, but I also want to know which loops didn't complete and why)
continue;
}
//do some assignements calculations
try {
doAnotherThing() // this method may throw a checked a exception
}
catch (MyCheckedException e) {
//Store my exception in a Map (this is all running in a loop and I want it to continue running, but I also want to know which loops didn't complete and why)
continue;
}
This is considering that you will handle ALL this checked exceptions exactly the same way of course.
Is it recommended to keep the lines
inside the try catch to bare minimum?
No. Can't imagine how you could think that the length of a try block or indeed of any block can have any impact on performance.
Does the code inside the try clause
run slower or cause any performance
hit?.
No.
As you observed, exceptions only incur performance costs when thrown.
If you're concerned about 'try' performance, surely the thing to do is keep the code inside to a maximum?
In your example here, the real performance hit is if both doSomething() and doAnotherThing() both throw exceptions. Entering a try-block is fast, until it throws an exception.
It really comes down to what your situation is. If you need to do the same thing when MyCheckedException is thrown either way, I'd consider it both more readable and more performant to have them both in the same try block, but if you need to handle the two different situations differently then of course it makes more sense to separate them.
Edit: I read the end of your comment, you're assuming handling both the same way, in which case I'd put them both in the same try-block.
I'm not sure which one is slower, but don't forget that a try block is control flow. You should make the control flow match what you're trying to accomplish. For me, the choice between
try {
// op 1.
// op 2.
/ ...
// op n.
}
catch ( MyCheckedException error )
{
// handle any `MyException` in op 1, 2 ... n.
}
and sepearate catch blocks for each is mainly a decision of whether I want to do different handling for each op, keep executing until op n regardless of errors or try to execute all of them and fail at the first error.
Write clean, readable code, and then search for bottlenecks. If existing experiments can't conclude to basic guidelines, then I suspect that's not where you'll find your bottlenecks anyways.
Having try-blocks should have basically zero performance effect in any decent JVM. The real hit comes when an exception is actually thrown.
You can read this article to get an idea of how the JVM implements exception handling in bytecode: it creates "exception tables" that map regions of code to catch/finally blocks, so:
Bytecode for a try-block is the same as for a standard { } block
The only extra cost in the non-throwing case is that of having the "exception table" loaded in memory.
Of course, when an exception is thrown there is a lot of stack work going on, so it is going to have a cost. Anyway, it is not nearly as bad as with SEH (.NET exceptions).
Your code should only handle the exceptions it can do something about, the others should be re-thrown.
The amount of code in the try block does not cause slowdowns, hitting the catch block does. But unless you are trying to write real high performance code, I would not worry about it.
Keeping the number of try/catch blocks to a minimum will improve performance slightly, but moving the work around won't really make a difference, except for work that would be skipped because of a thrown exception.
Exceptions cost a lot because each time an exception is thrown, the stack trace must be created and populated.
Imagine a balance transfer operation which fails in 1% of cases due to lack of funds.
Even with this relatively little rate of failures, performance may be severely impacted.
See source code and benchmark results here.
I'm not sure that inside the try block the performance might be slow, but what I do know is that the performance of ex.getStackTrace() is very slow because it reveals all of your command stack and you should be careful with that.
There is overhead for each exception block. So, you want to maximize the amount of time you stay in a block.
However, you also have to consider the difference in semantics. In your first example, if doSomething() throws an exception, then doAnotherThing() won't be run. In the second example (assuming the catch handler doesn't return), doAnotherThing() WILL be run.

Categories

Resources