Compiler forces to handle rethrow of unchecked exception - java

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();
}
}
}
}

Related

Maintaining multiple Exception types while exception chaining in single try-catch

I have a function that throws several different types of custom Exceptions. I wish to catch these exceptions from that function, add some important information, and then throw the exception as their original type to pass up the caller chain (exception chaining). I would like this to be compact in a single catch if possible.
I know Java 7+ has the functionality to handle multiple Exception types and throw them while maintaining their type. However, when exception chaining I cannot catch and throw multiple Exception types in the same catch block without losing the type. Is it possible to throw an exception maintaining its original type in a single catch block that accepts multiple Exception types? Or do I have to split it into 3 nearly-equivalent (essentially redundant) catch blocks?
Example:
void thisWorks() {
try {
someFunction(); // throws ExceptionA, ExceptionB, ExceptionC
} catch (ExceptionA | ExceptionB | ExceptionC exception) {
throw exception; // still has the original ExceptionA/ExceptionB/ExceptionC type
}
}
void whatIWant() {
try {
someFunction();
} catch (ExceptionA | ExceptionB | ExceptionC exception) {
// This throws an Exception, not the original ExceptionA/ExceptionB/ExceptionC type.
// Is it possible to fit this in a single block like the thisWorks() function?
// Or do I have to split into 3 catch blocks just for the throw type?
throw new Exception("Important information here", exception);
}
}
i don't think there simple approach if you don't like multiple catch my approach would be something like this but to me one way or the other you still have some redundance either mutiple catch or do multiple instanceof your exception.
try {
someFunction()
} catch (Exception ex) {
if (ex instanceof ExceptionA) {
throw new ExceptionA("Important information here", ex);
} else if(ex instanceof ExceptionB){
throw new ExceptionB("Important information here", ex);
} else {
throw new ExceptionC("Important information here", ex);
}
}
public class MyThrowClass {
public static void main(String[] args) throws Exception {
try {
someFuntion(1);
} catch (Throwable t) {
throw new Exception("Important information here", t);
}
}
public static void someFuntion(int value) throws ExceptionA, ExceptionB {
if (value == 1) {
throw new ExceptionA("Exception A");
}
throw new ExceptionB("Exception B");
}
}

Java exception handling with instantiate Exception superclass and IOException subclass

First I create a class called OrderHandler.java. I declared an instance of superclass Exception and an instance of subclass IOException in a main method.
Now the question is to show a compilation error when you try catching the superclass exception type before the subclass exception type. What should I do? Need I create some methods to show the path? Or do I need to instantiate the OrderHandler as well?
Thanks
import java.io.IOException;
public class OrderHandler {
public static void main(String[] args) {
// TODO Auto-generated method stub
Exception A = new Exception();
IOException B = new IOException();
}
}
You're not catching any exceptions in your sample code. I think you mean this:
try {
// do some stuff
} catch (Exception ex) {
// report a general exception
} catch (IOException ex) {
// report an IO exception
}
This isn't going to do what you want it to do. You need to catch more specific exceptions first, otherwise the IOException block will never execute. The correct way to do this is:
try {
// do some stuff
} catch (IOException ex) {
// report an IO exception
} catch (Exception ex) {
// report a general exception
}

Why getting handle or declare error, when already declared?

This is the code sample and I am getting an error "must be caught or declare to
be thrown" but I have
already handled the IOException. So can you please tell why the error is populating. The code also
follows the handle and declare rule.
public void rethrow() throws SQLException, IOException {
try {
couldThrowAnException();
}
catch(Exception e) {
e = new IOException();
throw e; //Error: must be caught or declare to be thrown
}
}
The problem you are running into is that the compiler deals with the variable declaration type, not the type you assign to the variable.
The variable is of type Exception, which is not part of the throws clause.
If you change the catch() clause to match IOException, it will compile.
I'd suggest you read the Exceptions Trail of the Java Language Tutorial.
You handled IOException but you are throwing Exception(not IOException ) from catch block.
So you have to add Exception in throws clause
or
catch IOException instead of Exception in the catch block
public void rethrow() throws SQLException, IOException {
try {
couldThrowAnException();
}
catch(IOException e) {
e = new IOException();
throw e; //Error: must be caught or declare to be thrown
}
}
Although, it makes no sens to cathc it and throw it...
A far better way would be:
public void rethrow() {
try {
couldThrowAnException();
}
catch(IOException e) {
//do something when you encounter the io-error
}
catch(SQLException e) {
//do something when you encounter the sql-error
}
}

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 handler for multiple exceptions?

I am experimenting with exceptions and i want to ask when it is possible to handle multiple exceptions in one handler and when it is not?
For example i wrote the following code which combines two exceptions (FileNotFoundException OutOfMemoryError) and the program runs properly without any error. Al thought the handling is not so relevant with the functionality of the code i chose them just to see when i can combine multiple exceptions in on handler :
import java.io.FileNotFoundException;
import java.lang.OutOfMemoryError;
public class exceptionTest {
public static void main(String[] args) throws Exception {
int help = 5;
try {
foo(help);
} catch (FileNotFoundException | OutOfMemoryError e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
public static boolean foo(int var) throws Exception {
if (var > 6)
throw new Exception("You variable bigger than 6");
else
return true;
}
}
But when i choose different type of exceptions the compiler gives me error . For example when i choose IOException and Exception i have the error the exception is already handled " :
import java.io.IOException;
import java.lang.Exception;
public class exceptionTest {
public static void main(String[] args) throws Exception {
int help = 5;
try {
foo(help);
} catch (IOException | Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
public static boolean foo(int var) throws Exception {
if (var > 6)
throw new Exception("You variable bigger than 6");
else
return true;
}
}
So why is this happening ? Why in one occasion i can use multiple exception in handler and in the other not ? Thank you in advance.
You are getting the message because IOException is a subclass of Exception. Therefore, if an IOException were thrown, it would be caught by a catch (Exception e) statement, so catching it as an IOException is redundant.
The first example works because neither FileNotFoundException nor OutOfMemoryError is a subclass the other.
However, you can catch sub-classed exceptions using the separate catch statement:
try{
// code that might throw IOException or another Exception
} catch (IOException e) {
// code here will execute if an IOException is thrown
} catch (Exception e) {
// code here will execute with an Exception that is not an IOException
}
If you do this, please note that the subclass must come first.

Categories

Resources