I am implementing exception handling in java with multiple exceptions.
Look at the following scenario:
Function f1 throws Exceptions e1, e2, e3 and e4
and Function f2 catches these.
Now I want to catch e1,e2 explicitly by catch(Exception e1 and e2) and the other exceptions should be caught all in the same block by catch(Exception e)
So e1 and e2 are a special case, and others are all general exceptions.
So will the following work?
try{
//some work`
} catch(ExceptionType1 e1) {
//do some special logging
} catch (ExceptionType2 e2) {
//do some special logging
} catch(Exception e) {
//do general logging for other exceptions
}
My question is whether ExceptionType1(e1) will also be caught by Exception e?
The Spec writes:
If execution of the try block completes abruptly because of a throw of a value V, then there is a choice:
If the run-time type of V is assignment compatible with (§5.2) a catchable exception class of any catch clause of the try statement, then the first (leftmost) such catch clause is selected. The value V is assigned to the parameter of the selected catch clause, and the Block of that catch clause is executed, and then there is a choice:
If that block completes normally, then the try statement completes normally.
If that block completes abruptly for any reason, then the try statement completes abruptly for the same reason.
Therefore, at most one catch block will be executed.
For that to work you need to have catch blocks with different Exceptions
like NullPointerException NumberFormatException and the general exception will be caught by catch block with Exception parameter since Exception is the super class of all Exceptions
try{
//some work`
} catch(NullPointerException e1) {
//do some special logging
} catch (NumberFormatException e2) {
//do some special logging
} catch(Exception e) {
//do general logging for other exceptions
}
Using your code will catch all Exceptions in catch(Exception e1){...}
The other catch-blocks are unused. If you want to handle different Exception-types on different way you have to give the catch(...) other Exception-types.
Like
try{
}catch(IOException e1){
// Do sth
}
catch(NullPointerException e2){
// Do sth else
}
// and so on...
You cannot have multiple catch blocks with the same class i.e. Exception
If you have multiple Exceptions you need to create a separate class for each one and make your catch block for a specific class
Just be aware the order of your catch block must go from the more specific to the more generic class
e.g.
try {
} catch (FileNotFoundException e) {
System.err.println("FileNotFoundException: " + e.getMessage());
} catch (IOException e) {
System.err.println("Caught IOException: " + e.getMessage());
} catch (Exception e) {
System.err.println("Caught Exception: " + e.getMessage());
} catch (Throwable e) {
System.err.println("Caught Throwable: " + e.getMessage());
}
So in the above code if the exception is of FileNotFoundException only the first catch will be executed. Otherwise the catch block with Exception is going to be executed for any instance of Exception class that was not caught in the previous catch blocks
At the end Throwable will catch anything that does not inherent from Exception such as Error
Related
Here is my code:
public static void main(String[] args) {
System.out.print("a");
try {
System.out.print("b");
throw new IllegalArgumentException();
} catch (IllegalArgumentException e) {
System.out.print("c");
throw new RuntimeException("1");
} catch (RuntimeException e) {
System.out.print("d");
throw new RuntimeException("2");
} finally {
System.out.print("e");
throw new RuntimeException("3");
}
}
I can not understand why the output is abce and RuntimeException("3")
That becomes clear when you indent your code as it should be:
try {
System.out.print("b");
throw new IllegalArgumentException();
} catch (IllegalArgumentException e) {
System.out.print("c");
throw new RuntimeException("1");
} catch (RuntimeException e) {
System.out.print("d");
throw new RuntimeException("2");
} finally {
System.out.print("e");
throw new RuntimeException("3");
}
The point is: there is only one try block. And the first catch block is taken. That one throws - and this exception 1 would be the one you notice in your stacktrace.
But thing is: the finally block is throwing "on top" of exception 1. Therefore you see exception 3.
In other words: there is a misconception on your end. You probably assume that exception 1 should be caught by the second catch block. And that is wrong. The second catch block only covers the first try block. Meaning: an exception from a catch block does not result in another catch block being taken. The first catch block "fires", and the finally block "fires" - leading to the observed results.
While you can have many catch() blocks, a maximum of 1 catch() will be executed when an exception is thrown. After that it will execute finally block, hence you have the output abce and the RuntimeException from finally block.
It is because, after IllegalArgumentException thrown in try block, it is caught in corresponding catch (IllegalArgumentException e) { } block. As finally block gets executed regardless of exception, e get printed.
To your question, Since the exception was already caught in catch block it will throw the corresponding exception accordingly and it will get propagated to the caller of that method.
Can we catch an exception type twice in the main method with different messages? I want to print out a different warning.
Ex:
try {
// some code
} catch (NumberFormatException e) {
System.out.println("Wrong input!");
} catch (NumberFormatException e) {
System.out.println("No valid number!");
}
You cannot catch the same exception type (like NumberFormatException) twice. I suggest you catch it once but in the catch block, you print two messages instead.
As i understand your comments you want to display the right message for your exception:
try {
// some code
} catch (NumberFormatException e) {
System.out.println(e.getMessage());
}
You can´t catch the same exception twice.
What you can do is to throw a custom exception in your code and catch it if you want a different behaviour.
try{
...
throw new YourException(yourMessage);
}catch(YourException e){
}
You can´t catch the same exception twice.
Consider the following example,
try {
} catch (FileNotFoundException e) {
System.err.println("FileNotFoundException: " + e.getMessage());
throw new SampleException(e);
} catch (IOException e) {
System.err.println("Caught IOException: " + e.getMessage());
}
Here,
Both handlers print an error message. The second handler does nothing else. By catching any IOException that's not caught by the first handler, it allows the program to continue executing.
The first handler, in addition to printing a message, throws a user-defined exception.
I have read the bug detectors in findbugs website, http://findbugs.sourceforge.net/bugDescriptions.html
I want to write a test code and use Findbugs to detect the REC error.
But the findbugs cannot. Why? Could you help me to solve this?
Thanks,
Below is the description in Findbugs.
REC: Exception is caught when Exception is not thrown (REC_CATCH_EXCEPTION)
This method uses a try-catch block that catches Exception objects, but Exception is not thrown within the try block, and RuntimeException is not explicitly caught. It is a common bug pattern to say try { ... } catch (Exception e) { something } as a shorthand for catching a number of types of exception each of whose catch blocks is identical, but this construct also accidentally catches RuntimeException as well, masking potential bugs.
A better approach is to either explicitly catch the specific exceptions that are thrown, or to explicitly catch RuntimeException exception, rethrow it, and then catch all non-Runtime Exceptions, as shown below:
try {
...
} catch (RuntimeException e) {
throw e;
} catch (Exception e) {
... deal with all non-runtime exceptions ...
}
My code is:
public static void test1(){
int A[] = {1,2,3};
int result = 5/0;//divided by 0
int arrOut = A[0]+A[4];//index out of bound
System.out.println(arrOut);
System.out.println(result);
try {
} catch (RuntimeException e) {
// TODO: handle exception
System.out.println("Runtimeex throw");
throw e;
} catch (Exception e) {
// TODO: handle exception
System.out.println("An try error occurred: 0 cannot be divided");
}
}
The try is where the exception occur that you want to catch. However, since it is occurring out of the try block, the exception is not caught by the catch part, which is why FindBugs reporting it as a useless try {...} catch {...} code. The proper code should be as follows.
int A[] = {1,2,3};
try {
int result = 5/0;//divided by 0
int arrOut = A[0]+A[4];//index out of bound
System.out.println(arrOut);
System.out.println(result);
} catch (RuntimeException e) {
// TODO: handle exception
System.out.println("Runtimeex throw");
throw e;
} catch (Exception e) {
// TODO: handle exception
System.out.println("An try error occurred: 0 cannot be divided");
}
}
class chain_exceptions{
public static void main(String args[]){
try
{
f1();
}
catch(IndexOutOfBoundsException e)
{
System.out.println("A");
throw new NullPointerException(); //Line 0
}
catch(NullPointerException e) //Line 1
{
System.out.println("B");
return;
}
catch (Exception e)
{
System.out.println("C");
}
finally
{
System.out.println("D");
}
System.out.println("E");
}
static void f1(){
System.out.println("Start...");
throw new IndexOutOfBoundsException( "parameter" );
}
}
I expected the Line 1 to catch the NullPointerException thrown from the Line 0 but it does not happen.
But why so ?.
When there is another catch block defined, why cant the NPE handler at Line1 catch it ?
Is it because the "throw" goes directly to the main() method ?
Catch{ . . . } blocks are associated with try{ . . . } blocks. A catch block can catch exceptions that are thrown from a try block only. The other catch blocks after first catch block are not associated with a try block and hence when you throw an exception, they are not caught. Or main() does not catch exceptions.
A kind of this for each catch block will do what you are trying to do.
try{
try
{
f1();
}
catch(IndexOutOfBoundsException e)
{
System.out.println("A");
throw new NullPointerException(); //Line 0
}
}
catch(NullPointerException e) //Line 1
{
System.out.println("B");
return;
}
The catch blocks are only for the try block. They won't catch exceptions from other catch blocks.
catch statements only catch exceptions thrown from a try { ... } block.
The NullPointerException is thrown from a catch { ... } block, not a try { ... } block.
To catch an exception thrown from a catch block you need to put another try block inside of it. Outside, wrapping the original try...catch would work, too.
A second catch doesn't catch the exception from the first catch block. You have to add another try-catch within the first catch block (or around the whole try-catch you already have) to make this run as expected.
Since java 7 you can use code below or an other option is to nest the try catch statements, there is no other option in java
try {
...
} catch( indexoutofboundsexception| nullpointerexception ex ) {
logger.log(ex);
throw ex;
}
Your catch clauses only catch exceptions thrown by f1(). They don't call exceptions thrown in other catch clauses of the same try-catch-finally construct.
Because f1() throws IndexOutOfBoundsException.
try
{
f1(); //throws IndexOutOfBoundsException
}
catch(IndexOutOfBoundsException e) //gets caught here immediately and does not check other catch blocks
{
System.out.println("A");
throw new NullPointerException(); //Line 0
}
Short answer: yes, the throw will directly throw the exception to the main method.
Generally, once a catch block is executed, it behaves like an else if, that is, it won't consider the other alternatives.
No, the reason it isn't being caught is because it isn't in the try block which is linked to the catch block. If you want to catch that exception as well, you would have to wrap the throw in a new try/catch group. The reason why you would want to do this tho, is a riddle to me.
What you also can do btw:
catch (IndexOutOfBoundsException|NullPointerException e)
This will also allow you to use the same catch block for multiple types of exceptions.
Your expectation was incorrect:
The catch blocks are associated with the try block. So once an exception is thrown inside of the try, it leaves that scope. Now you are in the scope outside the try, meaning you are no longer in any try/catch block. Any exceptions thrown here (when you re-throw) will not be caught by anything, and yes, bubble out of main.
You can not catch exception from another catch block, for that you probably need to do something like this, in your first catch block
System.out.println("A");
try{
throw new NullPointerException(); //Line 0
}
catch(NullPointerException e) //Line 1
{
System.out.println("B");
return;
}
I am using a try catch block to catch an exception. The console shows that it is throwing a null value. But it is not going to the catch block.
try {
System.out.println("Exception here "+SomeObject.getValue());
} catch (NullPointerException e) {
// TODO: handle exception
SomeObject so = new SomeObject();
}
SomeObject.setValue();
}
How could this be handled. Can I also use method level throws NullPointerException ?
It indeed would have went inside the catch block. There is another potential NullPointerException at the line (assuming you are trying to say)
so.setValue();
Having said that it is not advised to throw RuntimeException. It is better you handle NullPointerException in your code not through try/catch but through simple condition checks
it is a bad idea to catch UnChecked Exceptions, rather than catching NullPointerExcetpion, you can simple check for null values in an If condition.
if(SomeObject.getValue()!=null)
System.out.println(SomeObject.getValue());
You can put another try block inside catch
try {
doSomething();
} catch (IOException) {
try {
doSomething();
} catch (IOException e) {
throw new ApplicationException("Failed twice at doSomething" +
e.toString());
}
} catch (Exception e) {
}