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)
Related
I have a catch block with multiple exceptions - Arithmetic and NullPointer and one catch block with Exception. I am calling a method from catch block, but it is not find the instance of exception correctly.
try {
int a = 10/0;
} catch (ArithmeticException | NullPointerException e) {
Exce(e);
} catch (Exception e) {
Exce(e);
}
public static void Exce(ArithmeticException ex) {
System.out.println("Arithmetic");
}
public static void Exce(Exception ex) {
System.out.println("Exception");
}
But i am getting output as "Exception"..I am not sure why Arithmetic is not getting displayed
When i have separate catch block for Arithmetic and Null pointer..I am able to print "Arithmetic"..But catch with multiple exceptions not working...
If you split the ArithmeticException and NullPointerException into 2 catch blocks, it works as you expect. I assume this is because variable e is declared of type Exception to be able to hold ArithmeticException and NullPointerException.
public static void main(String[] args) {
try {
int a = 10 / 0;
} catch (ArithmeticException e) {
Exce(e);
} catch (NullPointerException e) {
Exce(e);
} catch (Exception e) {
Exce(e);
}
}
} catch (ArithmeticException | NullPointerException e) {
Exce(e);
}
The compile time type of e in the above is the union of ArithmeticException and NullPointerException. So when the compiler tries to match the type of e against the Exce methods:
The Exce(ArithmeticException) overload is not applicable because at runtime e could be a NullPointerException.
The Exce(Exception) overload is applicable because any value of e that matches the union of ArithmeticException and NullPointerException is an Exception as well.
Unfortunately, you cannot declare a method overload for the ArithmeticException | NullPointerException ... even if you wanted to:
If you want to handle ArithmeticException | NullPointerException together like this, you could declare an overload like this:
public static void Exce(RuntimeException ex) {
System.out.println("RuntimeException");
}
Alternatively, catch ArithmeticException and NullPointerException separately.
It is also possible to catch those two exception in one catch clause, and then discriminate them using (say) instanceof and type casts. But it is a lot more code to do that. (And a bad idea for other reasons.)
Assuming we are talking about all the exceptions that extends base Exception class,
is:
try {
some code;
} catch (InterruptedException e) {
e.printStackTrace();
} catch (ExecutionException e) {
e.printStackTrace();
}
catch (MyOwnException e)
{
e.printStackTrace();
}
same as:
try {
some code;
}
catch (Exception e) {
e.printStackTrace();
}
I am wondering in which case I MUST use the former one?
In the 2nd option Exception will catch all exception, not only those explicitly listed in the first option.
Use the 1st option if you want to catch only selected exceptions, and respond differently to each.
If you want to catch only selected exceptions, and have the same response to all of them, you could use:
catch (InterruptedException | ExecutionException | MyOwnException e)
{
e.printStackTrace();
}
It is good practice to use Exception sub classes rather than Exception class. If you use Exception then it would be difficult to debug.
Here is a link for reference
http://howtodoinjava.com/best-practices/java-exception-handling-best-practices/#3
If you have multiple exceptions which all are extending from...we'll say IndexOutOfBoundsException, then unless you specifically want to print a different message for StringIndexOutOfBoundsException or another sub-class you should catch an IndexOutOfBoundsException. On the other hand if you have multiple exceptions extending from the Exception class, it is proper format to create a multi-catch statement at least in JDK 1.8:
try {
// Stuff
}catch(InterruptedException | ClassNotFoundException | IOException ex) {
ex.printStackTrace();
}
The former one where you create multiple catch statements is if you were trying to do what I said before.
try {
// Stuff
}catch(StringIndexOutOfBoundsException se) {
System.err.println("String index out of bounds!");
}catch(ArrayIndexOutOfBoundsException ae) {
System.err.println("Array index out of bounds!");
}catch(IndexOutOfBoundsException e) {
System.err.println("Index out of bounds!");
}
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.
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.
In C#, I can use the throw; statement to rethrow an exception while preserving the stack trace:
try
{
...
}
catch (Exception e)
{
if (e is FooException)
throw;
}
Is there something like this in Java (that doesn't lose the original stack trace)?
catch (WhateverException e) {
throw e;
}
will simply rethrow the exception you've caught (obviously the surrounding method has to permit this via its signature etc.). The exception will maintain the original stack trace.
You can also wrap the exception in another one AND keep the original stack trace by passing in the Exception as a Throwable as the cause parameter:
try
{
...
}
catch (Exception e)
{
throw new YourOwnException(e);
}
I would prefer:
try
{
...
}
catch (FooException fe){
throw fe;
}
catch (Exception e)
{
// Note: don't catch all exceptions like this unless you know what you
// are doing.
...
}
In Java is almost the same:
try
{
...
}
catch (Exception e)
{
if (e instanceof FooException)
throw e;
}
In Java, you just throw the exception you caught, so throw e rather than just throw. Java maintains the stack trace.
Stack trace is prserved if you wrap the catched excetion into an other exception (to provide more info) or if you just rethrow the catched excetion.
try{
...
}catch (FooException e){
throw new BarException("Some usefull info", e);
}
something like this
try
{
...
}
catch (FooException e)
{
throw e;
}
catch (Exception e)
{
...
}
public int read(byte[] a) throws IOException {
try {
return in.read(a);
} catch (final Throwable t) {
/* can do something here, like in=null; */
throw t;
}
}
This is a concrete example where the method throws an IOException. The final means t can only hold an exception thrown from the try block. Additional reading material can be found here and here.
I was just having a similar situation in which my code potentially throws a number of different exceptions that I just wanted to rethrow. The solution described above was not working for me, because Eclipse told me that throw e; leads to an unhandeled exception, so I just did this:
try
{
...
} catch (NoSuchMethodException | SecurityException | IllegalAccessException e) {
throw new RuntimeException(e.getClass().getName() + ": " + e.getMessage() + "\n" + e.getStackTrace().toString());
}
Worked for me....:)