When to Catch the Exception VS When to Throw the Exceptions

Catching versus Throwing Exceptions in Java

Throwing Exceptions

In your first example,

public void whileChatting() throws IOException{}

means that it will just throw the exception to whatever is calling the function. It can then be caught while calling that method with a try-catch block. such as

try{
whileChatting();
}
catch(IOException e){
e.printStackTrace();
}

Throwing a method basically propagates it up the chain, and so any method that calls this method will need to also include throws IOException, or the exception will need to be dealt with in the higher level method (by means of a try-catch block usually).

Catching Exceptions

Catching an exception is a way to gracefully deal with exceptions. The common thing to do is e.printStackTrace(); which prints details of the error to the console, however it's not always necessary. Sometimes you may want to do a System.exit(0) or even a System.out.println("Error in method whileCalling()")

With a catch block you can catch any type of exception! you can also do a try-catch-finally block which will run the code in the try block, catch any exceptions, and whether or not any exceptions are caught it will enter the finally block and run that code.

To know what Exception you might need to catch, you can look at the Javadocs for the class that may throw the exception. There you will find a list of every possible thing that the class can throw. You can also just catch Exception which will catch any Exception imaginable! (Well, granted it extends Exception)

And finally you can link catch blocks together like so.

try{
whileCalling();
}
catch(IOException e){
//handle this situation
}
catch(FileNotFoundException e){
//handle this situation
}
catch(Exception e){
//handle this situation
}

This will work like and else-if block and not catch duplicates.

So to answer your questions basically:

1: To throw an Exception means to have somebody else deal with it, whether this be another class, another method, or just to hoping it doesn't happen or else your program will crash(pretty bad practice).

2: To use a try catch block is to actually deal with the Exception however you see fit! printing out the stacktrace for debugging or giving the user a new prompt to re-input something maybe. (For instance a prompt that the user needs to enter a file location and then it throws a FileNotFoundException)

Hope that helps!

When should we throw exceptions, or catch exceptions, in a method?

You throw an exception if your code can't do its job (also known as "fulfilling its contract"). This might happen because the caller passed you invalid input, or some external resource is malfunctioning (such as a lost network connection).

Catch an exception when there's an anticipated problem downstream that you can handle somehow. For example, you might catch exceptions indicating network problems and retry the operation a couple of times, or you might display an error message to the user and ask what to do next.

If downstream code might throw an exception but your code is somewhere in the middle and doesn't know what to do, just let the exception travel up to the calling code.

Throwing and Catching Exceptions

You generally catch an exception in a method when you want your program to continue running. You throw an exception when you want a higher level method that is calling that method to handle the exception instead. For example, you might throw it all the way back to your Main method, which has a try..catch block (likely with different catch blocks for different exceptions) encapsulating all your method calls, and exceptions can be handled there (for example by ending the program).

Remember that throwing an exception will end the method immediately. This affects the flow of your code. If you might have an exception in the middle of the method, and the code below it can't run if that exception happened, then you would need to either wrap the whole section in a try/catch block or throw an exception.

A general word of advice - printStackTrace() is bad. You can create better error output yourself (and you can include the stack trace as well with your output). Even better, use logging.

I recommend reading this introduction to exceptions and this article which covers good and bad exception patterns.

What is the difference between try-catch and throws Exception in terms of performance?

From the paper, Optimizing Java Programs in the Presence of Exceptions:

The Java language specification requires that exceptions be precise,
which implies that:

  1. when an exception is thrown, the program state observable at the entry of the corresponding exception handler must be the same as in
    the original program; and
  2. exception(s) must be thrown in the same order as specified by the original (unoptimized) program.

To satisfy the precise exception requirement, Java compilers disable
many important optimizations across instructions that may throw an
exception...This hampers a wide range of program optimizations such as
instruction scheduling, instruction selection, loop transformations,
and parallelization.

In presence of a try-catch block, JVM maintains an exception table. For each new catch block, the compiler will add an entry to the exception table. If an exception occurs, JVM needs to go through each entry in the table and check if the exception is defined in the exception table (this requires type analysis too). The result is a much more complex control structure which in turn will greatly hamper compiler optimization.

throws on the other hand, allows the exception to propagate. Although this might be better for performance, an uncaught exception can potentially crash the thread, the whole application, or even kill the JVM itself!

How to decide when to use try-catch?

I think correctness and reliability concerns play a more important role than performance here. But if you have only performance in mind, the authors in this link have done extensive bench-marking for java code in presence of exceptions. Their most basic conclusion is that if you use exceptions for truly exceptional cases (not as a means for program flow control) there will not be much of a performance hit.

Should I throw exceptions in an if-else block?

It makes no sense to throw an exception in a try block and immediately catch it, unless the catch block throws a different exception.

Your code would make more sense this way:

public Response getABC(Request request) {
Response res = new Response();
if (request.someProperty == 1) {
// business logic
} else {
res.setMessage("xxxx");
}
return res;
}

You only need the try-catch block if your business logic (executed when the condition is true) may throw exceptions.

If you don't catch the exception (which means the caller will have to handle it), you can do without the else clause:

public Response getABC(Request request) throws Exception {
if (request.someProperty != 1) {
throw new Exception("xxxx");
}

Response res = new Response();
// business logic
return res;
}

Throwing exceptions as well as catching exceptions?

The catch block has greater priority over the method level throw declarations. If something would pass by that catch block, it would be thrown by the method (but that's not the case since all your mentioned exceptions are indeed inheriting from the Exception).

If you need an exception to be handled by the catch block but forwarded further, you would have to rethrow it, e.g.

throw e;


Related Topics



Leave a reply



Submit