tl;dr Mutlicatch handles things singlehandedly, multiple catch blocks are more flexible and nicer to operations. The two techniques can be combined.
If you have a try statement that can throw many different exception types, you'll want the multiple catch blocks. It's a bit more code but offers far greater flexibility.
For instance, if working with sockets, a SocketException may be caught with nothing more than a reconnect and/or an error message (as something as simple as an inadvertently disconnected cable may cause this)
If a null pointer exception(although it's unchecked) is caught, you're going to want to write to a log and make an emergency landing here, cleaning up what you can, and backtracking quite a bit codewise, possibly.
In addition, this can be subdivided even further, where different types of "common" exceptions may cause different actions to be taken(such as a connection lost vs name not resolved having different implications for the end-user on the first connection attempt) and different "heavy" exceptions being handled in different ways as well.
While you could have one (multiple exception type) catch block, it would either singlehandedly take similar action for all exceptions (presenting a null pointer exception to a user in the same way as a condition based on a cable being unplugged) or require if e instanceof FooException blocks that can decrease readability.
You can also combine the two, multicatching all "common" exceptions into a retry and nice message and all severe exceptions into a forced cleanup and shutdown
You don't want stacktraces for tripped cables, and you don't want to brush off missing objects.
Answer from nanofarad on Stack Overflowtl;dr Mutlicatch handles things singlehandedly, multiple catch blocks are more flexible and nicer to operations. The two techniques can be combined.
If you have a try statement that can throw many different exception types, you'll want the multiple catch blocks. It's a bit more code but offers far greater flexibility.
For instance, if working with sockets, a SocketException may be caught with nothing more than a reconnect and/or an error message (as something as simple as an inadvertently disconnected cable may cause this)
If a null pointer exception(although it's unchecked) is caught, you're going to want to write to a log and make an emergency landing here, cleaning up what you can, and backtracking quite a bit codewise, possibly.
In addition, this can be subdivided even further, where different types of "common" exceptions may cause different actions to be taken(such as a connection lost vs name not resolved having different implications for the end-user on the first connection attempt) and different "heavy" exceptions being handled in different ways as well.
While you could have one (multiple exception type) catch block, it would either singlehandedly take similar action for all exceptions (presenting a null pointer exception to a user in the same way as a condition based on a cable being unplugged) or require if e instanceof FooException blocks that can decrease readability.
You can also combine the two, multicatching all "common" exceptions into a retry and nice message and all severe exceptions into a forced cleanup and shutdown
You don't want stacktraces for tripped cables, and you don't want to brush off missing objects.
This a choice thing. You want to balance readability, portability, maintainability and also handling different exceptions differently.
So balance the use ... If all your catches use the same block of handling then use the first form, because that's just one code block and you aren't repeating yourself over and over again. The compiler can optimize things out a bit for you.
On the other hand use the second form if you are handling each exception differently.
This is somewhat of a broad question and the answer is dependant on your goals.
java - Multiple or Single Try Catch - Stack Overflow
Is there such thing as too many try-catch blocks?
java - Best practice for handling many exceptions - Software Engineering Stack Exchange
Avoiding duplicate code in multi-catch block
Videos
I always try to reduce levels of nesting for readability and maintainability. If you have n try/catch blocks, each handling the same type of exception, why not refactor the code that can throw the exception into methods...it would look something like:
try {
firstBatchOfTricky();
secondBatchOfTricky();
....
nthBatchOfTricky();
} catch (ItWentBoomException e) {
// recover from boom
} catch (ItWentBangException e) {
// recover from bang
}
This is much more readable than having multiple try/catches. Note that your methods should describe what they do in the spirit of self documenting code.
Since you have your own Exception type, you can add the data you need to the exception to do different things in the catch block. When you say 'more specific message', you can just throw the exception with the detailed message; you shouldn't need multiple catch blocks. If you want to do drastically different things based on the state of the exception, just create more exception types and catch blocks but only one try block, as my pseudocode shows...
Finally, if you can't recover from the exception(s), you should not clutter the code with catch blocks. Throw a runtime exception and let it bubble. (Good advice from @tony in the comments)
This isn't a performance or personal preferences question: It's a functionality and requirements question.
Suppose I write:
Scenario 1:
try
{
doThingA();
}
catch (SomeException panic)
{
System.out.println("doThingA failed");
}
try
{
doThingB();
}
catch (SomeException panic)
{
System.out.println("doThingB failed");
}
Scenario 2:
try
{
doThingA();
doThingB();
}
catch (SomeException panic)
{
System.out.println("doThingA or doThingB failed");
}
These two scenarios are not equivalent: They do different things. In Scenario 1, if doThingA throws the exception, doThingB still executes. In Scenario 2, if doThingA throws the exception, doThingB is not executed. So the question is not which gives better performance or which is more readable code, but rather, if doThingA fails, should doThingB still be executed or not?
If what you really want is the second behavior, but you want different messages to tell the user what went wrong, then you should either throw different exceptions, or put the text of the message into the exception, i.e.
void doThingA() throws SomeException
{
... whatever code ...
if (theWorldIsAboutToEnd)
throw new SomeException("doThingA failed");
}
Then in the catch clause, instead of displaying a constant string, displayt SomeException.toString or SomeException.getMessage.
I have to make a mini social media app for an assignment, where users can update their status, change their profile picture, change their profile details, or submit a complaint. Any time there's user input like this I have it in a try-catch block since we get deducted major points if our app crashes. Mine doesn't crash when I test it but I'm not sure what kinds of tests our teacher will be putting it through during grading.
Generally speaking are try-catch blocks this the right way to go about this sort of thing? Safeguarding the app from crashing even if the intended functionality doesn't work? Thanks a lot!
Edit: I found all your comments really helpful and will only be implementing try-catch blocks for when a user attempts to upload an image to the app and it's not found. For the string input I'll be validating the input rather than wrapping those methods in try-catch. Really appreciate the help, I learned a lot! Thanks all!
I have a try-catch block that handles multiple exception; if an IOException is thrown, the exception will be handled elsewhere in the program and the program will keep running. If any other exceptions are thrown, the program should exit.
So I'd like to to something like this, instead of writing System.exit(1) in every catch block:
void foo() throws IOException {
try {
bar(); // Throws IOException as well as Exception 1, 2, 3
} catch (Exception1 e) {
logStuff();
} catch (Exception2 e) {
logStuff();
} catch (Exception3 e) {
logStuff();
}
if (Exception 1, 2 or 3 was thrown) {
System.exit(1);
}
}
The log messages are specific to each catch block, so I can't group them into one block. So, is there a simple way to avoid multiple System.exit(1)?