try {
} catch() {}
finally {
try {
} catch() { }
finally { }
}
Is it good to have the code like above?
Yes, you can do this.
Actually, you are even required to do it when dealing with streams you want to close properly:
InputStream in = /* ... */;
try {
} catch (...) {
} finally {
try {
in.close();
} catch (...) {
} finally {
}
}
I don't see any case in which this would be a bad practice
For readability you can factor out the nested try-catch in to a separate method, like:
try{
}catch(){}
finally{
cleanup();
}
And the second try-catch can be inside the cleanup method.
To support the above pattern in IO package, JAVA6 introduces a new class called Closeable that all streams implement, so that you can have a single cleanup method as follows:
public static boolean cleanup(Closeable stream)
{
try{
stream.close();
return true;
}catch(){
return false;
}
}
It is best to avoid it when you can, but sometimes it may be necessary. If you tell us more about why you think you need this, we may be able to give better answers :-)
One reason to think about may be to commit a transaction in the finally block, when the commit operation itself may throw an exception.
It is important to note that exceptions thrown inside a finally block may easily shadow exceptions thrown earlier, within the try block, unless handled properly. Thus such nested try/catch blocks are sometimes the way to go. However, as others have noted, to improve readability, it is advisable to extract the insides of the finally block into a separate method.
It's ugly, but there are cases where you can't avoid it, especially in resource clean up where you have dependent resources and the clean up of one resource can throw an exception.
A typical example is tidying up ResultSet, Statement and Connection objects in JDBC code. Closing the ResultSet can throw an exception, but we'd still like to continue and close the Statement and Connection
Looks ugly but sometimes it's the way to go. Depending on the code consider to extract a method with the second try-catch-finally block.
Related
The Oracle Java documentation for the then-new try-with-resources shows all examples with the AutoCloseable in question being constructed in the try(...):
try (BufferedReader br = new BufferedReader(new FileReader(path))) {
...
}
That seems secure in the sense that even if the constructor (as opposed to some subsequent event) already acquires resources that have to be released, they would be released if we ran into an exception.
However, as, e.g., https://www.baeldung.com/java-try-with-resources points out, starting with Java 9, we can use effectively final resources initialized before the try(...):
FileOutputStream fos = new FileOutputStream("output.txt");
try (fos) {
// do stuff
}
In a similar, pre-Java-9 vein, I have seen:
CustomStreamLikeThing connection = new CustomStreamLikeThing("db_like_thing");
// ... do some stuff that may throw a RuntimeException
try (CustomStreamLikeThing connection2=connection) {
// do some more stuff
}
Which seems legal, but at the same time to somewhat weaken the concept: If the CustomStreamLikeThing acquires closeable resources, they may not be released.
Are there guidelines about when the constructor of an AutoCloseable should be enclosed in the try(...), or is this a matter of taste (as in "enclose all those things that I think could throw an exception")?
You should always use try-with-resources if you can.
When you allocate a resource, you should make sure the resource is always released when you're done with it. That "always" generally means that you should use a try-finally, so that any error occurring after the resource is allocate won't prevent the resource from being released.
Which means that if you don't use try-with-resources, you need to use try-finally, so why did I say to always use try-with-resources?
Because calling close() can fail too, and try-with-resources handles that for you, with a feature added when try-with-resources was added, called suppressed exceptions.
You'll know the importance of this if you've ever cursed at a stacktrace of a failed close() call, that has replaced the exception thrown by the code that should have been in a try-with-resources block, so you now don't know what actually caused the problem.
Suppressed exceptions is a commonly overlooked feature, but is a great time saver when a cascaded exception is thrown by a close method. For that alone, always use try-with-resources.
Side benefit: Try-with-resources is less code than using try-finally, and you should definitely use one of those two when handling resources.
Are there guidelines about when the constructor of an AutoCloseable should be enclosed in the try(...), or is this a matter of taste (as in "enclose all those things that I think could throw an exception")?
The basic rule in coding is: you do anything on purpose. Which requires that you understand what you are doing, and what each "thing" in your code is doing.
Meaning: if you have something that needs to be "closed", then the common sense rule is: use try with resources.
But you are asking specifically about the subtle aspect of the "object creation". Should that go into the try(), or can it be done before?!
For that: no hard rules, as long as your source code does semantically the right thing. Therefore, it boils down to these two aspects:
You talk to your team, and you agree on your "preferred" style, and then your whole team follows that. In other words: pick the style you prefer, and then stick to that: be consistent!
You look at your requirements. Your try(fos) option works with java9. For people that don't have to patch older products, that is fine. But for people that regularly have to patch "the same change" to different versions of the same product ... those people might prefer source code that can just be merged into a java8 environment.
When having the constructor directly in the try-with-resources statement like this:
try (MyCloseable c = new MyCloseable()) {
// do stuff with c
} catch (IOException e) {
// handle exception
}
then the catch block will be called when any of the following throw an exception:
the constructor
the try-body
the close()-method.
So you can't have a catch block for every special case when e.g. all throw an IOException.
Whereas with code like this, you can control the exception handling a bit more:
MyCloseable c;
try {
c = new MyCloseable();
} catch (IOException e) {
// handle constructor exception
}
try (c) {
// do stuff with c
} catch (IOException e) {
// handle exception from close() or try-body
}
But then again, you still have a single catch block for the try-body and the close method in the above example, and doing something like this would not be recommended:
// initialize c like in the second example
try (c) {
try {
// do stuff with c
} catch (IOException e) {
// handle try-body exception
}
} catch (IOException e) {
// handle close() exception
}
The pre-java 9 is just hack to allow autoclosable to work on the underlying object and close and release resources.
With java 9, it's more embedded in the language itself to allow closing of resources initialized outside the try with block.
In terms of preference, it's more about whether its elegant by the time you finish the try with block, if it becomes too huge, might as well move it out.
This question already has an answer here:
What does "error: unreported exception <XXX>; must be caught or declared to be thrown" mean and how do I fix it?
(1 answer)
Closed 8 months ago.
While learning Java I stumble upon this error quite often. It goes like this:
Unreported exception java.io.FileNotFound exception; must be caught or declared to be thrown.
java.io.FileNotFound is just an example, I've seen many different ones. In this particular case, code causing the error is:
OutputStream out = new BufferedOutputStream(new FileOutputStream(new File("myfile.pdf")));
Error always disappears and code compiles & runs successfully once I put the statement inside try/catch block. Sometimes it's good enough for me, but sometimes not.
First, examples I'm learning from do not always use try/catch and should work nevertheless, apparently.
Whats more important, sometimes when I put whole code inside try/catch it cannot work at all. E.g. in this particular case I need to out.close(); in finally{ } block; but if the statement above itself is inside the try{ }, finally{} doesnt "see" out and thus cannot close it.
My first idea was to import java.io.FileNotFound; or another relevant exception, but it didnt help.
What you're referring to are checked exceptions, meaning they must be declared or handled. The standard construct for dealing with files in Java looks something like this:
InputStream in = null;
try {
in = new InputStream(...);
// do stuff
} catch (IOException e) {
// do whatever
} finally {
if (in != null) {
try {
in.close();
} catch (Exception e) {
}
}
}
Is it ugly? Sure. Is it verbose? Sure. Java 7 will make it a little better with ARM blocks but until then you're stuck with the above.
You can also let the caller handle exceptions:
public void doStuff() throws IOException {
InputStream in = new InputStream(...);
// do stuff
in.close();
}
although even then the close() should probably be wrapped in a finally block.
But the above function declaration says that this method can throw an IOException. Since that's a checked exception the caller of this function will need to catch it (or declare it so its caller can deal with it and so on).
Java's checked exceptions make programmers address issues like this. (That's a good thing in my opinion, even if sweeping bugs under the carpet is easier.)
You should take some appropriate action if a failure occurs. Typically the handling should be at a different layer from where the exception was thrown.
Resource should be handled correctly, which takes the form:
acquire();
try {
use();
} finally {
release();
}
Never put the acquire() within the try block. Never put anything between the acquire() and try (other than a simple assign). Do not attempt to release multiple resources in a single finally block.
So, we have two different issues. Unfortunately the Java syntax mixes up the two. The correct way to write such code is:
try {
final FileOutputStream rawOut = new FileOutputStream(file);
try {
OutputStream out = new BufferedOutputStream(rawOut);
...
out.flush();
} finally {
rawOut.close();
}
} catch (FileNotFoundException exc) {
...do something not being able to create file...
} catch (IOException exc) {
...handle create file but borked - oops...
}
When should I use code snippet A instead of snippet B (i.e. what are the benefits of using snippet A)?:
Snippet A:
try {
// codeblock A
}
catch (Exception ex) {
// codeblock B
}
finally {
//codeblock C
}
Snippet B:
try {
// codeblock A
}
catch (Exception ex) {
// codeblock B
}
//codeblock C
Use a finally block if you have code that must execute regardless of whether or not an exception is thrown.
Cleaning up scarce resources like database connections are a good example.
An obvious case is when you re-raise or throw another exception in your catch block.
It's useful if you need to do some cleanup, e.g. close a database connection. Because "finally" is executed always, you don't need to do the bug-prone copy-paste of the same code in the end of the "try" and in also in one or more "catch" blocks.
You must almost always use the snippet with finally block when you have resources that needs clean up in both successful or error scenarios. A typical example is the jdbc connection object which should always be closed (clean up) in the finally block.
Imagine to have a return statement inside the catch block: the C block will not be executed in snippet B, but in snippet A it will, before returning.
How do I do a try except else in Java like I would in Python?
Example:
try:
something()
except SomethingException,err:
print 'error'
else:
print 'succeeded'
I see try and catch mentioned but nothing else.
I'm not entirely convinced that I like it, but this would be equivalent of Python's else. It eliminates the problem's identified with putting the success code at the end of the try block.
bool success = true;
try {
something();
} catch (Exception e) {
success = false;
// other exception handling
}
if (success) {
// equivalent of Python else goes here
}
What about this?
try {
something();
} catch (Exception e) {
// exception handling
return;
}
// equivalent of Python else goes here
Sure, there are some cases where you want to put more code after the try/catch/else and this solution don't fit there, but it works if it's the only try/catch block in your method.
While Ryan's answer of tracking errors with boolean(s) is nice, I think using a "logic block" to "skip forward" is better in this case.
In Java, you are allowed to create arbitrary context blocks (scopes) using <optional-label-name followed by ':'>{...} and assign labels to them. You can than call break <labelname>;
Here is an example of what I mean that you can play with:
private static void trycatchelsetest(boolean err) {
myLogicBlock: {
try {
System.out.println("TRY");
{ //unlabeled block for demonstration
if(err)
throw new IOException("HELLO!");
}
} catch(IOException e) {
System.out.println("CATCH");
break myLogicBlock;
} finally {
System.out.println("FINALLY");
}
System.out.println("ELSE");
}
System.out.println("END");
}
The reason Try doesn't have an else is because it is meant to catch a specific error from a specific block of code, which is either handled (usually by setting a default or returning), or bubbled up (and finally is offered only to make sure resources aren't leaked because of the interrupt, even if you break out). In the break example above, we are handling the exception by skipping the block of code that is no longer relevant because of the error (skipping forward to the next logical step). The boolean example by Ryan handles it by noting the error happened, and letting latter parts of the code react to it happening after the fact.
I think the logic block is better than the boolean approach (as long as you have no complex logic based on what errors have been thrown) because it doesn't require the reader to know the entire function to understand what happens. They see break <labelname>; and know that the program will effectively skip forward to the end of that block. The boolean requires the programmer to track down everything that makes decisions on it.
Obviously, "Skip-forward" and Boolean tracking each have their own advantages, and will usually be more a style choice.
While there is no built-in way to do that exact thing. You can do something similar to achieve similar results. The comments explain why this isn't the exact same thing.
If the execution of the somethingThatCouldError() passes, YAY!! will be printed. If there is an error, SAD will be printed.
try {
somethingThatCouldError();
System.out.println("YAY!!");
// More general, code that needs to be executed in the case of success
} catch (Exception e) {
System.out.println("SAD");
// code for the failure case
}
This way is a little less explicit than Python. But it achieves the same effect.
I think on the following examples; but could not figure out what the importance of the finally block is. Can you tell me the difference of the executions of these two code samples? Also a real life example can be helpful.
Sample 1:
try{
// some code 1
}catch(Exception ex){
// print exception
}finally{
// some code 2
}
Sample 2:
try{
// some code 1
}catch(Exception ex){
// print exception
}
// some code 2
There is a big difference in the two snippets you've presented, e.g. when the catch block itself throws an exception, the finally block would still be executed by its semantics.
That is the following snippet prints "Finally!", but not "What about me???":
try {
throw null; // throws NullPointerException!
} catch (Exception e) {
int oops = 1/0; // throws ArithmeticException!
} finally {
System.out.println("Finally!"); // still gets executed!
}
System.out.println("What about me???"); // doesn't get executed!
Generally speaking, the finally of a try block practically always gets executed. There's no such guarantee for any code following the try block.
But what if my catch block is just a simple print statement?
There's still no guarantee that it won't throw something. Something could still go wrong in e.g. the construction for the exception detailed message.
Even if you make a best effort guarantee that the catch code is "safe" and the code following the try statement will always be executed, the question then becomes "Why?". Why avoid finally but then try so hard to replicate its semantics?
finally semantics is guaranteed, requiring no burden of proof from either the writer or the reader of the code. Precisely because of this, it's idiomatic to use finally block to put mandatory "clean-up" code. Using finally guarantees correctness and enhance both writability and readability.
The finally block is executed even if e.g. an Error is thrown, which is not caught by the catch block in your example. So you can put cleanup code in the finally block, which should be run always, regardless of the outcome of the operations in the try and catch blocks.
Note that usually catch blocks catch more specific types of exceptions - often only checked exceptions -, so in most cases the difference between the two code examples above is very definite.
Update: you may say that your catch block can never throw an exception, so finally is not needed. However, note two things:
this is only the current state of the code, and it can change in the future - can you guarantee that the future programmer who adds some potentially exception-throwing code in the catch block, will remember to put the cleanup code after it into a finally block?
try-catch-finally is a programming idiom which makes it easier for people reading the code to understand what's going on. If you don't use the common idiom, you risk misunderstanding, thus bugs on the long term.
You use the finally block in order to cleanup and run any code that should run whether an exception was thrown (and caught) or not. This includes code that you have in the catch block.
it is helpful when we want to free up the resources we used in try block. So the only place to execute them without missing at any case is finally block. Since if exception is thrown, java does not execute code which immediate after that. it directly jump to the catch block.
Note that you can have even try-finally without a catch:
try{
// some code
}finally{
// cleanup code
}
An example therefore could be a method that wants to propagate exceptions to the caller, but still needs clean up code, like releasing a look.
In case where the statements in try block throw unchecked exceptions, finally block will get executed allowing programmer to take relevant actions.
In real life, the finally block is used to close opened resources even if an exception occurs.
For example, when you read (or write) a file, when you access to a database, etc.
public void readFile(String fileName) {
FileReader fr;
BufferedFileReader bfr;
try {
fr = new FileReader(fileName);
bfr = new BufferedFileReader(fr);
// ...
} catch (IOException ioe) {
// ...
} finally {
// TO ENSURE THAT THE READERS ARE CLOSED IN ALL CASES
if (bfr != null) {
try {
bfr.close();
} catch (IOException ignoredIOE) {}
}
if (fr != null) {
try {
fr.close();
} catch (IOException ignoredIOE) {}
}
}
}