The Difference Between Try/Catch/Throw and Try/Catch(E)/Throw E

The difference between try/catch/throw and try/catch(e)/throw e

The constructions

try { ... }
catch () { ... } /* You can even omit the () here */

try { ... }
catch (Exception e) { ... }

are similar in that both will catch every exception thrown inside the try block (and, unless you are simply using this to log the exceptions, should be avoided). Now look at these:

try { ... }
catch ()
{
/* ... */
throw;
}

try { ... }
catch (Exception e)
{
/* ... */
throw;
}

try { ... }
catch (Exception e)
{
/* ... */
throw e;
}

The first and second try-catch blocks are EXACTLY the same thing, they simply rethrow the current exception, and that exception will keep its "source" and the stack trace.

The third try-catch block is different. When it throws the exception, it will change the source and the stack trace, so that it will appear that the exception has been thrown from this method, from that very line throw e on the method containing that try-catch block.

Which one should you use? It really depends on each case.

Let's say you have a Person class with a .Save() method that will persist it into a database. Let's say that your application executes the Person.Save() method somewhere. If your DB refuses to save the Person, then .Save() will throw an exception. Should you use throw or throw e in this case? Well, it depends.

What I prefer is doing:

try {
/* ... */
person.Save();
}
catch(DBException e) {
throw new InvalidPersonException(
"The person has an invalid state and could not be saved!",
e);
}

This should put the DBException as the "Inner Exception" of the newer exception being throw. So when you inspect this InvalidPersonException, the stack trace will contain info back to the Save method (that might be sufficient for you to solve the problem), but you still have access to the original exception if you need it.

As a final remark, when you are expecting an exception, you should really catch that one specific exception, and not a general Exception, ie, if you are expecting an InvalidPersonException you should prefer:

try { ... }
catch (InvalidPersonException e) { ... }

to

try { ... }
catch (Exception e) { ... }

Good luck!

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.

try{} catch(Exception e){} VS try{} catch(Exception e){ throw;} - What the difference?

This will re-throw the same exception and keep the stack trace. This will make debugging easier.

catch(Exception e)
{
//something
throw;
}

This will rethrow the exception, but you'll lose the stack trace.

catch(Exception e)
{
//something
throw e;
}

This will silently swallow the exception. You only want to do this when you're catching a specific exception rather than Exception. You should generally have a good reason for doing so.

try
{
//something
}
catch(Exception e)
{
//something
}

What is the difference between try-finally and try-catch-throw?

Think of it like this...

try
{
//do some stuff
}
catch
{
//do some stuff if there was an exception
//maybe some cleanup, maybe rethrow exception
}
finally
{
//always do this stuff exception or not
}

Is there a difference between throw and throw ex ?

Yes, there is a difference.

  • throw ex resets the stack trace (so your errors would appear to originate from HandleException)

  • throw doesn't - the original offender would be preserved.

     static void Main(string[] args)
    {
    try
    {
    Method2();
    }
    catch (Exception ex)
    {
    Console.Write(ex.StackTrace.ToString());
    Console.ReadKey();
    }
    }

    private static void Method2()
    {
    try
    {
    Method1();
    }
    catch (Exception ex)
    {
    //throw ex resets the stack trace Coming from Method 1 and propogates it to the caller(Main)
    throw ex;
    }
    }

    private static void Method1()
    {
    try
    {
    throw new Exception("Inside Method1");
    }
    catch (Exception)
    {
    throw;
    }
    }

Exception handling Try-Catch block difference

Using a catch without a parameter is no longer useful as of framework 2.0, as all unmanaged exceptions are wrapped in a managed exception. Before that you could use it to catch exceptions thrown by unmanaged code.

You can specify just the type of the exception if you don't want to use any information from it, but usually you would want a name for it so that you can get to the information:

try {
// some code
} catch(Exception) {
// i don't care about any information in the Exception object, just the type
}

vs.

try {
// some code
} catch(Exception ex) {
// use some information from the exception:
MessageBox.Show("Internal error", ex.Message);
}

You should always try to have an exception type that is as specific as possible, as that makes it easier to handle the exception. Then you can add less specific types to handle other exceptions. Example:

try {
// some database code
} catch(SqlException ex) {
// something in the database call went wrong
} catch(Exception ex) {
// something else went wrong
}


Related Topics



Leave a reply



Submit