what is the most efficient way to handle an exception parameter to a method

advertisements

I have a method which is getting an exception as a parameter to a particular method. This method needs to do perform different logic based on the type of exception. Between below two ways of handling this.. what is the most efficient way (is there a third better way).. and why

public void processException(Exception ex) {
   try {
      throw ex;
   } catch(CustomException e1) {
      //do something
   } catch (CustomException2 e2) {
      //do something else
   }
}

or

public void processException(Exception ex) {
   if (ex instanceof CustomException) {
      // do something
   } else if (ex instanceof CustomException2) {
      // do something else
   }
}


Efficiency aside, the second way is preferred, because the exception is not thrown in a non-exceptional situation. The first way to "dispatch" uses exception throwing in a regular control flow, which makes it harder to read your program.

Besides, the two methods are not identical: the first program must be declared as throwing a checked exception, because not all subtypes are handled by the catch blocks.

If you are dealing with custom exceptions that your program defines, you have a way to avoid checking the subtype: since Exception objects are regular classes, you could add a package-visible method to them, and have them implement a package-visible interface holding that method. Exceptions would then be able to override that method, letting you use a regular "virtual" dispatch rather than checking for the exact class type at runtime.

Here is an illustration of this approach: let's say you want your exceptions to write themselves to a log file. You can do this as follows:

interface LoggableException {
    void logToFile();
}
public class CustomExceptionOne extends Exception implements LoggableException {
    ...
    public void logToFile() {
        // Do something
    }
}
public class CustomExceptionTwo extends Exception implements LoggableException {
    ...
    public void logToFile() {
        // Do something else
    }
}
public void processException(Exception ex) {
    if (ex instanceof LoggableException) {
        LoggableException lEx = (LoggableException)ex;
        lEx.logToFile();
    }
}