Exception Handling; Try Catch - java

Here's my code:
class FinallyDemo {
static void myMethod(int n) throws Exception{
try {
switch(n) {
case 1:
System.out.println("1st case");
return;
case 3:
System.out.println("3rd case");
throw new RuntimeException("3!");
case 4:
System.out.println("4th case");
throw new Exception("4!");
case 2:
System.out.println("2nd case");
}
catch (RuntimeException e) {
System.out.print("RuntimeException: ");
System.out.println(e.getMessage());
} finally {
System.out.println("try-block entered.");
}
}
public static void main(String args[]){
for (int i=1; i<=4; i++) {
try {
FinallyDemo.myMethod(i);
} catch (Exception e){
System.out.print("Exception caught: ");
System.out.println(e.getMessage());
}
System.out.println();
}
}
}
Now, doesnt it work this way:
If I have a try and catch block in the method itself then I need not write
method_name(int n) throws Exception?
Doesnt try-catch block in the method that throws exception prevents from writing "throws exception" in the method that throws exception?

In your example, the case 4 throws an exception while in the catch you are just catching the RuntimeException. Since there is not catch for Exception, your method needs to declare that it throws Exception.
If you were to add a catch for Exception, you wouldn't need to throw Exception. This will work.
static void myMethod(int n) {
try {
switch (n) {
case 1:
System.out.println("1st case");
return;
case 3:
System.out.println("3rd case");
throw new RuntimeException("3!");
case 4:
System.out.println("4th case");
throw new Exception("4!");
case 2:
System.out.println("2nd case");
}
} catch (RuntimeException e) {
System.out.print("RuntimeException: ");
System.out.println(e.getMessage());
} catch (Exception e) {
System.out.print("Exception: ");
System.out.println(e.getMessage());
}
finally {
System.out.println("try-block entered.");
}
}

You don't need the throws clause if and only if the type of exception being thrown is caught (or if it extends RuntimeException. In your case, you throw an Exception with the statement throw new Exception("4!");, but you only catch the type RuntimeException.
If you add a catch block for Exception, then you will no longer need the throws clause. For example:
static void myMethod(int n) throws Exception{
try {
switch(n) {
case 1:
System.out.println("1st case");
return;
case 3:
System.out.println("3rd case");
throw new RuntimeException("3!");
case 4:
System.out.println("4th case");
throw new Exception("4!");
case 2:
System.out.println("2nd case");
}
} catch (RuntimeException e) {
System.out.print("RuntimeException: ");
System.out.println(e.getMessage());
} catch(Exception e) {
System.out.print("Exception: ");
System.out.println(e.getMessage());
} finally {
System.out.println("try-block entered.");
}
}

Yes, provided you're catching all exception types that can be thrown by the method.
In your code, you throw an Exception but do not supply a catch block for it (you are only catching RuntimeException), therefore you must declare your method as throwing Exception
You would need:
...
catch (RuntimeException e) {
System.out.print("RuntimeException: ");
System.out.println(e.getMessage());
} catch (Exception e) {
System.out.print("Exception: ");
System.out.println(e.getMessage());
} finally {
...

Doesnt try-catch block in the method that throws exception prevents from writing "throws exception" in the method that throws exception?
No, you can always declare to throw exceptions, even if you do not.
Among other things this is useful to allow subclasses to throw them (because they are not allowed to add additional throw clauses). It also allows you to later change the implementation without changing the exception interface.

Right now are tow types of exceptions
Subclasses of Exception.
Subclasess of RuntimeException
The subclasses of Exception are know as checked exception and the compiler ensures that these are managed in try/catch block or through the modifier throws Exception (or subclass) on method.
The subclasess oF RuntimeException are know as unchecked exception and the compile don't require any mechanism for manage it.
Now if you use the modifier throws Exception (or subclass) on a method the compiler will require you manage it with try/catch.

Since you throw both a RuntimeException and an Exception in the switch, you either need to catch both or the method needs to throw the Exception so it can be handled in the method calling myMethod
To catch both use:
catch (RuntimeException e) {
System.out.print("RuntimeException: ");
System.out.println(e.getMessage());
}catch (Exception e) {
System.out.print("Exception: ");
System.out.println(e.getMessage());
}
Make sure the catch of Exception is always last, otherwise it will also catch the RuntimeException since it extends Exception

You are handling the exception in TWO ways. Firstly if you extend the directly call the Exception class as you have done when declaring the method
method_name(int n) throws Exception
What this means is that no matter what type of exception occurs in the method it will always be able to catch it, For example if an Arithmetic Exception or a NullPointerException or an ArrayIndexOutOfBoundsException occurs inside the method your above declaration will be able to catch each and every one of them. Because of that there is no actual purpose of having the try catch block as well placed inside that method because even RunTimeException is part of the Exception Class hierarchy.
Therefore if I understood your question correctly the program will execute and then catch the exception from the catch block, failing which it will catch it from the method declaration.
Hope it answers your query.

Related

How does exception chain work in my code?

Why this code doesn't print "d". Why it doesn't go to the catch block for RunTimeException?
public static void main(String[] args) {
System.out.println("a");
try {
System.out.println("b");
throw new IllegalArgumentException();
} catch (IllegalArgumentException e) {
System.out.println("c");
throw new RuntimeException();
}catch (RuntimeException e) {
System.out.println("d");
throw new RuntimeException();
}finally{
System.out.println("e");
throw new RuntimeException();
}
}
The output of this program is
a
b
c
e
Exception in thread "main" java.lang.RuntimeException
EDIT: After throwing IllegalArgumentException it goes to the corresponding catch block and prints 'c'. after that since we don't catch the exception in RuntimeException it doesn't go any further. but since it's guranteed that we go to the finally block it print 'e' and after that throw RunttimeException. if the code was like something like the following, it would throw out the RuntimeException("2"). If we comment the exception inside finally, it throw out RuntimeException("1").
public static void main(String[] args) throws InterruptedException {
System.out.println("a");
try {
System.out.println("b");
throw new IllegalArgumentException();
} catch (IllegalArgumentException e) {
System.out.println("c");
throw new RuntimeException("1");
}catch (RuntimeException e) {
System.out.println("d");
throw new RuntimeException();
}finally{
System.out.println("e");
throw new RuntimeException("2");
}
}
The reason of this code not printing d is, because in the IllegalArgumentException catch block, after printing "c" and before throwing RuntimeException it executes finally (that's how the flow works). Finally block throws exception itself, so It never gets to throw that RuntimeException that gets it to "d".
public static void main(String[] args) {
System.out.println("a");
try {
System.out.println("b"); // 1
throw new IllegalArgumentException(); // 2
} catch (IllegalArgumentException e) {
System.out.println("c"); // 3
throw new RuntimeException(); // nope, there's a finally block that executes first
}catch (RuntimeException e) {
System.out.println("d");
throw new RuntimeException();
}finally{
System.out.println("e"); // 4
throw new RuntimeException(); // 5 - rest of the code never got executed.
}
}
Hope this was clear enough.
Also, as it was pointed out, even if the RuntimeException after "c" was executed, It would not invoke the lower catch block. The catch block is only invoked once, depending on the Exception thrown in the try block (though this isn't really relevant because the first explanation dictates the flow of your thread).
The catch blocks are NOT in the scope of the try. Any code in the catch blocks executes in the context of the outer main code, and thus has no exception handlers. When you throw RuntimeException the finally block for the try gets executed and then the exception terminates the program.
In try catch block, if one of the catch block catches the exception the other catches doesn't get involved. remeber that finally block always run at the end no matter exception gets threw or not.

Why customize Exception doesn't catch this? (JAVA)

look at the next code lines please:
public void methodBla(){
try{
system.out.println(2/0);
{
catch(MyArithmeticException me){
system.out.println("Error: My exception");
}
catch(Exception a){
system.out.println("Error: general exception");
}
}
I don't understand why, when I'm trying to catch an ArithmeticException with my customize class: MyArithmeticException which extends ArithmeticException.
Public class MyArithmeticException extends ArithmeticException{
public MyArithmeticException(String str){
super("My Exception " + str);
}
}
MyArithmeticException doesnt catch it, its only catch the second "catch"(catch(Exception a)).
Thanks
Z
It is simple, because the statement 2/0 doesn't throw a MyArithmeticException. It throws ArithmeticException and since you didn't catch ArithmeticException, it is catched by the second catch.
The java language doesn't know if you want to derive your own exception type from any language defined exception. So if you need to throw your own type you should catch it and re-throw it as a ArithmeticException:
public void methodBla(){
try{
try{
system.out.println(2/0);
catch(ArithmeticException e){
throw new MyArithmeticException(e);
}
}
catch(MyArithmeticException me){
system.out.println("Error: My exception");
}
catch(Exception a){
system.out.println("Error: general exception");
}
}
Good Luck.
The problem is that an Arithmetic exception would be thrown. Not a "MyAritmeticException" so it cant be caught by the first catch clause, so it results to the second catch clause.
In other words, 2/0 will throw an AritmeticException which is the superclass of your exception thus it will not triger the MyArithmeticException catch block because thats a subclass.
If you want to customise the message of the exception you can do that in the catch statement, where you can get the message by Exception#getMessage() or Exception#getLocalizedMessage(); (the difference of the two can be found here)

Compiler forces to handle rethrow of unchecked exception

I have encountered a scenario while working with exceptions, following is the sample code.I am trying to understand why following code fails to compile. I am checking the exception type before rethrow which is unchecked exception.
public class TestException {
public void test() throws FileNotFoundException {
FileReader test = new FileReader("");
}
public static void main(String[] args){
TestException test=new TestException();
try {
test.test();
} catch (Exception e) {
// TODO Auto-generated catch block
if(e instanceof ArithmeticException){
throw e;
}
else{
e.printStackTrace();
}
}
}
}
You are still throwing a reference variable e of type Exception. Exception is a checked type. The compiler only knows the reference variable's type, not the referenced object's. If you want to keep main's method signature as-is, you'll need to either wrap e into an unchecked exception type (such as ArithmeticException):
if(e instanceof ArithmeticException){
throw new ArithmeticException(e.getMessage());
}
or cast it as an unchecked exception:
if(e instanceof ArithmeticException){
throw (ArithmeticException)e;
}
Since the reference variable e is of type java.lang.Exception, throw e will throw checked exception. Thus it has to be declared in throws section in the method signature.
Try changing your catch block as follows:-
if(e instanceof ArithmeticException){
throw (ArithmeticException)e;
}
else{
e.printStackTrace();
}
You could also use a hack with Generics to throw an checked Exception as an unchecked one:
http://www.gamlor.info/wordpress/2010/02/throwing-checked-excpetions-like-unchecked-exceptions-in-java/
I like to use this over throw new RuntimeException(e), since the latter creates unnecessary output in a Stacktrace and its harder to catch somewhere else (you have to check the cause instead of the excetion itself).
catch (Exception e) {
Here is the effective declaration of e.
if(e instanceof ArithmeticException){
Here you are doing a runtime check of the type of e.
throw e;
At this point the compile-time type of e is Exception. So the compiler enforces its rules.
I will suggest to use two catch blocks.
typechecking in catch block is not a good practice where you can catch that specific class using other catch statement.
catch (ArithmeticException e) {
// TODO Auto-generated catch block
throw e;
}
catch(Exception e)
{
e.printStackTrace();
}
#Silly Freak I agree with you.
If you throw any exception then you should handle it but in your program your are able to throw but nowhere you are handling the exception, so just handle the exception by adding throws in main class like this:-
package first;
import java.io.FileNotFoundException;
import java.io.FileReader;
class A3{
public void test() throws FileNotFoundException {
FileReader test = new FileReader("");
}
public static void main(String[] args) throws Exception{
A3 test=new A3();
try {
test.test();
} catch (Exception e) {
// TODO Auto-generated catch block
if(e instanceof ArithmeticException){
throw e;
}
else{
e.printStackTrace();
}
}
}
}

Java7 multiple exception handling

I have been trying to find out answer to this question but did not get any satisfactory explanation. Here is some background:
Java 7 allows us to catch multiple exceptions in a single catch block provided those exceptions are from diffrent hierarchy. Eg:
try {
// some code
} catch(SQLException | FileNotFoundException e) {
e.printStackTrace();
} catch(Exception e) {
e.printStackTrace();
}
But if exceptions are from the same hierarchy we must use multiple catch blocks like:
try {
// some code
} catch(FileNotFoundException e) {
e.printStackTrace();
} catch(IOException e) {
e.printStackTrace();
}
But if I try to write code like below compiler complains that "The exception FileNotFoundException is already caught by the alternative IOException"
try {
// some code
} catch(FileNotFoundException | IOException e) { // compiler error
e.printStackTrace();
}
Now my question is: Why compiler reports an error in last case, can't it figure out that FileNotFoundException is special case of IOException? This would save code duplication when my exception handling logic is same.
Why compiler reports an error in last case, can't it figure out that FileNotFoundException is special case of IOException?
Because FileNotFoundException is a subclass of IOException. In other words, the "FileNotFoundException |" part is redundant.
The reason why the code below is ok...
} catch(FileNotFoundException e) {
...
} catch(IOException e) {
...
}
...is because here the IOException clause matters: If a SocketException is thrown for instance, it will pass the by the FileNotFoundException part, and get caught in the IOException clause.
When catching an exception you have order your catch clauses from the most specific to the most general.
Consider the following hierachy:
class MyException extends Exception {}
class MySubException extends MyException {}
If a part of your code throws MyException an an other part throws MySubException you have to catch MySubException first.
catch(MySubException e){
} catch(MyException e){
}
Its the same thing like using the instanceof operator.
If you test if an instance of MySubException is an instanceof MyException the result will be true.
mse = new MySubException();
if(mse instanceof MyException){
println("MyException");
} else if(mse instanceof MySubException){
println("MySubException");
}
This piece of code will never print "MySubException".
mse = new MySubException();
if(mse instanceof MySubException){
println("MySubException");
} else if(mse instanceof MyException){
println("MyException");
}
This would be the correct order.
Its because FileNotFoundException extends IOException, as you said its of same hierarchy, you cannot add them to same catch block.

Catch exceptions without a try block?

I have a lot of custom exceptions that I'm throwing in a specific cases in the code, and I'd like to have one catch block at the bottom of the method to handle them all.
All the exceptions are children of the Exception class CribbageException, so I'd like to have:
public void myMethod(){
if (whatever){
throw new CardException();
}
if (something else){
throw new InvalidCardException();
}
if (scenario 3){
throw new TwoCardsException();
}
catch (CribbageException e) {
System.out.println(e.getMessage());
}
}
But I'm getting a catch without try error.
Is there any way to use this type of exception handling?
Wrap all the throws inside a single try.
public void myMethod(){
try {
if (whatever){
throw new CardException();
}
if (something else){
throw new InvalidCardException();
}
if (scenario 3){
throw new TwoCardsException();
}
}
catch (CribbageException e) {
System.out.println(e.getMessage());
}
}

Categories

Resources