Java: catching specific Exceptions - java

say I have the following
try{
//something
}catch(Exception generic){
//catch all
}catch(SpecificException se){
//catch specific exception only
}
What would happen when it comes across SpecificException ? Does it catch it as a generic exception first, and then catch the specificexception ?
Or does it only catch SpecificException while ignoring generic exceptions.
I don't want both generic and specificexception being caught.

This won't compile. You'll be told that the specific exception block isn't reachable.
You have to have the more specific exception catch block first, followed by the general one.
try
{
//something
}
catch(SpecificException se)
{
//catch specific exception only
}
catch(Exception generic)
{
//catch all
}

No. All exceptions would be caught by the first block. The second will never be reached (which the compiler recognizes, leading to an error due to unreachable code). If you want to treat SpecificException specifically, you have to do it the other way round:
}catch(SpecificException se){
//catch specific exception only
}catch(Exception generic){
//catch all
}
Then SpecificException will be caught by the first block, and all others by the second.

This does not compile with eclipse compiler:
Unreachable catch block for IOException. It is already handled by the catch block for Exception
So define them the other way. Only the specific one will be caught.

The catch blocks are tried in order, and the first one that matches the type of the exception is executed. Since Exception is the superclass of all exception types, it will always be executed in this instance and the specific cases will never be executed. In fact the compiler is smart enough to notice this and raise a compilation error.
Just reorder the catch clauses.

As a side note, the only way to have both catch blocks called is to use nested exceptions.
try {
try{
//something
}catch(SpecificException se){
//catch specific exception only
throw se;
}
}catch(Exception generic){
//catch all
}

My proposition - catch SQLException and check code.
try {
getConnectionSYS(dbConfigFile, properties);
} catch (SQLException e){
if (e.getErrorCode()==1017){
getConnectionUSER(dbConfigFile, properties);
} else {
throw e;
}
}

Related

What are the restriction for code inside catch block

So are there any specific restrictions for writting code inside catch block?
PS. This question was asked by my friend's java programming teacher on the exam.
In this feature, now you can catch multiple exceptions in single catch block. Before java 7, you was restricted to catch only one. To specify the list of expected exceptions a pipe (‘|’) character is used.
Lets understand using an example.
try
{
//Do some processing which throws NullPointerException; I am sending directly
throw new NullPointerException();
}
//You can catch multiple exception added after 'pipe' character
catch(NullPointerException | IndexOutOfBoundsException ex)
{
throw ex;
}
Remember: If a catch block handles more than one exception type, then the catch parameter is implicitly final. In this example, the catch parameter ex is final and therefore you cannot assign any values to it within the catch block.
According to JLS:
CatchClause:
catch ( {VariableModifier} CatchType Identifier ) Block
So, you can write anything you can write in any other block.

Exception hierarchy/try-multi-catch

try {
throw new FileNotFoundException();
} catch (IOException e) {
e.printStackTrace();
}
catch (Exception e) {
e.printStackTrace();
}
Can someone tell me why the second catch block is not considered as unreachable code by the compiler? But in the following case:
try {
throw new FileNotFoundException();
} catch (Exception e) {
e.printStackTrace();
}
catch (IOException e) {
e.printStackTrace();
}
The second catch block is considered unreachable?
After all, FileNotFoundException comes under IOException, just as it comes under Exception.
Edit Please clarify:
The compiler will know an exception is thrown by a method based on the method's throws clause. But it may not necessarily know the specific type of exception (under that class of exception). So if a method throws exception 'A', compiler won't know if the actual exception is 'A' or a subtype of 'A' because this is only determined at runtime. The compiler however will know that an exception of type 'X' is never thrown, so giving a catch block for X is erroneous. Is this right?
The compiler cannot assume that the only possible exception thrown from your try block will be a FileNotFoundException. That's why it doesn't consider the 2nd catch block to be unreachable in your first code sample.
What if, for some unknown reason, a RuntimeException gets thrown while creating the FileNotFoundException instance (entirely possible)? What then?
In your first code sample, that unexpected runtime exception would get caught by the 2nd catch block, while the 1st block would take care of the FileNotFoundException if it gets thrown.
However, in your 2nd code sample, any and all exceptions would get caught by the 1st catch block, making the 2nd block unreachable.
EDIT:
To better understand why the catch(Exception e) block in your first code is not considered unreachable by the compiler, try the following code, and notice how the the 2nd catch is definitely reachable:
public class CustomIOException extends IOException {
public CustomIOException(boolean fail) {
if (fail) {
throw new RuntimeException("the compiler will never know about me");
}
}
}
public static void main(String[] args) {
try {
throw new CustomIOException(true);
} catch(IOException e) {
System.out.println("Caught some IO exception: " + e.getMessage());
} catch(Exception e) {
System.out.println("Caught other exception: " + e.getMessage());
}
}
Output:
Caught other exception: the compiler will never know about me
TL;DR
The compiler considers that FileNotFoundException() may not be the only Exception thrown.
Explaination
JLS§11.2.3 Exception Checking
A Java compiler is encouraged to issue a warning if a catch clause can
catch (§11.2) checked exception class E1 and the try block
corresponding to the catch clause can throw checked exception class
E2, a subclass of E1, and a preceding catch clause of the immediately
enclosing try statement can catch checked exception class E3 where E2
<: E3 <: E1.
That means that if the compiler considers that the only exception possibly thrown by your catch block is a FileNotFoundException(), it will warn you about your second catch block. Which is not the case here.
However, the following code
try{
throw new FileNotFoundException();
} catch (FileNotFoundException e){
e.printStackTrace();
} catch (IOException e){ // The compiler warns that all the Exceptions possibly
// catched by IOException are already catched even though
// an IOException is not necessarily a FNFException
e.printStackTrace();
} catch (Exception e){
e.printStackTrace();
}
This happens because the compiler evaluates the try block to determine which exceptions has the possibility to be thrown.
As the compiler does not warn us on Èxception e, it considers that other exceptions may be thrown (e.g RunTimeException). Since it is not the compiler's work to handle those RunTimeExceptions, it lets it slip.
Rest of the answer is intersting to read to understand the mechanism behind exception-catching.
Schema
As you may see, Exception is high in the hierarchy so it has to be declared last after IOException that is lower in the hierarchy.
Example
Imagine having an IOException thrown. As it is inherited from Exception, we can say IOException IS-A Exception and so, it will always be catched within the Exception block and the IOException block will be unreachable.
Real Life Example
Let's say, you're at a store and have to choose pants. The seller tells you that you have to try the pants from the largest ones to the smallest ones and if you find one that you can wear (even if it is not your size) you must take it.
You'll find yourself buying pants too large for your size and you'll not have the chance to find the pants that fits you.
You go to another store : there, you have the exact opposite happening. You can choose your pants from smallest to largest and if you find one you can wear, you must take it.
You'll find yourself buying pants at your exact size.
That's a little analogy, a bit odd but it speaks for itself.
Since Java 7 : multi-catch
Since Java 7, you have the option to include all the types of Exceptions possibly thrown by your try block inside one and only catch block.
WARNING : You also have to respect the hierarchy, but this time, from left to right.
In your case, it would be
try{
//doStuff
}catch(IOException | Exception e){
e.printStackTrace();
}
The following example, which is valid in Java SE 7 and later,
eliminates the duplicated code:
catch (IOException|SQLException ex) {
logger.log(ex);
throw ex;
}
The catch clause specifies the types of exceptions that the block can
handle, and each exception type is separated with a vertical bar (|).
First case:
catch (IOException e) { // A specific Exception
e.printStackTrace();
}
catch (Exception e) { // If there's any other exception, move here
e.printStackTrace();
}
As you can see, first IOException is catched. This means we are aiming at just one specific exception. Then in second catch, we aim for any other Exceptions other than IOException. Hence its logical.
In second:
catch (Exception e) { // Move here no matter whatever exception
e.printStackTrace();
}
catch (IOException e) { // The block above already handles *Every exception, hence this won't be reached.
e.printStackTrace();
}
We catched any exception (whether its IOException or some other Exception), right in the first block. Hence second block will not be reached because everything is already included in first block.
In other words, in first case, we aim at some specific exception, than at any other exceptions. While in second case, we first aim at all/any Exception, than at a specific exception. And since we already dealt will all exceptions, having a specific exception later won't make any logical sense.

Why does an empty try block with catch Exception compile? [duplicate]

This question already has answers here:
Java unreachable catch block compiler error
(7 answers)
Closed 7 years ago.
A try block without any code :
try {
} catch (Exception ex) {
// what Exception it is catching
ex.printStackTrace();
}
The absence of any code means that throwing an exception is impossible, so why doesn't this give an "unreachable catch block" compile error?
Exception includes RuntimeExceptions, which are unchecked and don't need to be declared, so Exception can always be validly caught.
I think this is an unimportant edge case.
That's valid Java syntax. It's the same as having an empty if-block:
if (condition) {
}
... or defining an empty method:
public void empty() {
}
... or only having comments as part of the body:
try {
// try body
} catch (Exception e) {
// catch body
}
All of that is valid syntax, so the compiler is happy. Further, since a blank line / empty body is totally ok, no exceptions will be thrown in the body of the try block during runtime, so the code would execute just fine as well.
So I am assuming that your question is what Exception will get caught and the answer is none. The exception would only be caught if while running the code within the try block throws an exception. It will then check to see if that exception was caught (FYI Exception will catch all exceptions), if yes it handles it inside the catch block otherwise it causes an error. Since there is nothing in the try block the exception will never be caught because no exception can ever be thrown.

Unhandled Java exception execute remainder of method?

I was responding to a slough of basic Java practice test questions and the correct answer to the following question slipped past me while taking the test.
Question: "If an exception is not caught, the finally block will run and the rest of the method is skipped - TRUE or FALSE?"
I am attempting to prove out the answer with the ThrowTest class (pasted at bottom) but I find Java exception handling to be somewhat unfamiliar. I compile the class as is with the ArrayIndexOutOfBoundsException portion of the catch block commented out. I then execute the class without passing an input parm thus creating an exception (the ArrayIndexOutOfBoundsException exception) . I would expect the final System.out.println would not execute and indeed it does not.
I find if I un-comment the ArrayIndexOutOfBoundsException catch block and recompile, the class then catches that specific error at run time and executes the "Rest of method" println at bottom. So, does my code prove the rest of "the rest of the method is skipped" or do I have to test it from a method other than the main method? Maybe there is a more straightforward method of testing it.
public class ThrowTest
{
public static void main(String[] args)
{
try
{
String anyString = args[0];
System.out.println("Try code executes");
}
catch(SecurityException e) //any old exception
{
System.err.println ("Error: SecurityException. ");
e.printStackTrace();
}
/* begin comment
catch(ArrayIndexOutOfBoundsException e)
{
System.err.println("Error: Caught ArrayIndexOutOfBoundsException. ");
e.printStackTrace();
}
end comment */
finally
{
System.out.println("finally block executes!");
}
System.out.println("Rest of method executes!");
}
}
Regardless of what exception is thrown a finally block will always execute (barring any strange situations like out of memory), so given the following
try {
// do some code
}
catch (SomeException e) {
// exception handling
}
finally {
doFinallyStuff();
}
doOtherStuff();
doFinallyStuff will always execute here. But doOtherStuff will only execute under the following conditions:
No exceptions are thrown
SomeException is thrown and the catch block does not rethrow the exception up the chain
If another exception is thrown in the try block that is not handled by the catch block, doFinallyStuff will still execute, but doOtherStuff will not
Your code is indeed proving that everything works as you described. When you catch an exception, then the rest of the method thereafter executes. If you let the method throw the exception, its execution halts immediately. Either way, the finally block will always execute.

basic Java question: throwing an exception to a later catch clause?

If you have:
catch (FooException ex) {
throw new BarException (ex);
}
catch (BarException ex) {
System.out.println("hi");
}
...and the first catch clause is triggered (i.e. FooExcepetion has occurred),
does the new BarException get immediately caught by the subsequent "catch" clause?
Or is the new BarException thrown one level up the continuation stack?
I realize this is a basic question. : )
It does not get caught by the 2nd catch clause, no.
Each catch clause in the list is tried, to see if it matches. The first one that matches is the only one that runs, then the code moves on to the finally clause.
Another result of this is that if you have:
try {
throw SubTypeOfException(...);
} catch(Exception e) {
... block 1 ...
} catch(SubTypeOfException e) {
... block 2 ...
}
then block 1 is the only one that will run, even though block 2 would have matched. Only the first matching catch clause is evaluated.
It's thrown one level up.
You'll need another try//catch block.

Categories