What Are Checked Exceptions in Java/C#

What are checked exceptions in Java/C#?

Checked exceptions are exceptions that the compiler require you handle in some way.

In Java, checked exceptions are Throwables that are not RuntimeException, Error, or one of their subclasses.

The Java designers felt they were needed to ensure programs handled exceptions that were reasonably likely. A classic example is IOException. Any time a program does I/O, there is a possibility of failure. The disk could be full, the file might not exist, there might be a permissions problem, etc.

Thus, Java is designed such that a program must syntactically handle the exception in some way. This could be with a catch block, or by rethrowing the exception in some way.

C# does not have checked exceptions. They decided to leave this issue up to the application developers (interview). Checked exceptions are controversial because they can make code verbose, while developers sometimes handle them trivially with empty catch blocks. Further, it can be arbitrary which standard library methods throw checked exceptions. For instance, why doesn't File.delete (a new Java 7 API does this differently) throw IOException?

Another concern Hejlsberg noted in that interview is versionability. Adding a checked exception to a throw clause forces all code using that method to be modified and recompiled.

Why are Exceptions not Checked in .NET?

Because the response to checked exceptions is almost always:

try {
// exception throwing code
} catch(Exception e) {
// either
log.error("Error fooing bar",e);
// OR
throw new RuntimeException(e);
}

If you actually know that there is something you can do if a particular exception is thrown, then you can catch it and then handle it, but otherwise it's just incantations to appease the compiler.

Why are exceptions named checked and unchecked?

If you call a method which is declared to throw a checked exception (such as IOException), the compiler will check that you're either catching it or declaring that you rethrow it. Likewise, in order to throw such a checked exception in the first place, the compiler checks that you've declared it as part of the method signature.

Basically, it's a little bit like type checking, except in terms of which exceptions can be thrown by a method.

The compiler doesn't perform any checking for unchecked exceptions - so they can be thrown by any method, without the method declaring them.

checked and unchecked exception in .NET

In Java, checked and unchecked exceptions don't exactly map to a fatal or non-fatal error. A checked exception explicitly is stating that the exception may be thrown and someone must catch it (to try to handle it or throw it up the stack), but there is no guarantee that the error may not be fatal (i.e. a syntax error in an SQL query will throw an SQLException and will likely be fatal, but it is a checked exception). An unchecked exception just means that someone doesn't need to catch it, but you still can if you want. It would typically indicate a programming error. Java Errors typically indicate things that are unrecoverable problems (such as an OutOfMemoryError).

The C# design of unchecked exceptions just means you don't need to catch the exceptions, and if uncaught will crash the application. Checked vs unchecked exceptions has been a long standing debate in the development community and there are pros and cons to both. Typically though, you can't do something about an exception and it frequently just ends up getting logged rather than handled, so C# made exceptions unchecked. When you can handle them (for example, if you want to retry an IO operation), you can still catch them and retry.

checked exception in C#

C# does not support checked exceptions. You can read up on why the original design did not include checked exceptions.

Link: The Trouble with Checked Exceptions

What are the pros and cons of checked exception?

Meh.

Checked exceptions are a great thing when used properly, but more often than not they lead to stuff like:

doSomething();
try
{
somethingThrowsCheckedException();
}
catch(ThatCheckedException)
{ }
doSomethingElse();

And, frankly, that's just wrong. You should let exceptions you don't handle bubble up.

Checked exceptions used properly can be good. But very frequently, the result of doing checked exceptions properly is method signatures like this:

public void itMightThrow() throws Exception1, Exception2, Exception3, Exception4, // ...
Exception12, Exception13, /* ... */ Exception4499379874
{
// body
}

Am I exaggerating? Only slightly.

Edit:

That said, one thing I prefer about C# over Java when it comes to exception handling has nothing to do with checked exceptions (I can get that if I go with Spec# anyway). No, what I like is that the stack trace in C# is populated when you throw an exception, rather than when you instantiate one as it is in Java.

Edit 2: This is for the commenters @Yishai, @Eddie, @Bill K:

First, you should check out this thread for information on how to get a stack trace without instantiating an exception. Keep in mind that walking the stack is a heavy process and should not be done on a regular basis.

Second, the reason I like C#'s exception stack trace being populated at throwal rather than at instantiation is that you can do things like this:

private MyException NewException(string message)
{
MyException e = new MyException(message);
Logger.LogException(message, e);
return e;
}

// and elsewhere...
if(mustThrow)
{
throw NewException("WHOOOOPSIEE!");
}

That's a trick you can't do in Java without having the NewException method included in the stack trace.

Understanding checked vs unchecked exceptions in Java

Many people say that checked exceptions (i.e. these that you should explicitly catch or rethrow) should not be used at all. They were eliminated in C# for example, and most languages don't have them. So you can always throw a subclass of RuntimeException (unchecked exception)

However, I think checked exceptions are useful - they are used when you want to force the user of your API to think how to handle the exceptional situation (if it is recoverable). It's just that checked exceptions are overused in the Java platform, which makes people hate them.

Here's my extended view on the topic.

As for the particular questions:

  1. Is the NumberFormatException consider a checked exception?
    No. NumberFormatException is unchecked (= is subclass of RuntimeException). Why? I don't know. (but there should have been a method isValidInteger(..))

  2. Is RuntimeException an unchecked exception?
    Yes, exactly.

  3. What should I do here?
    It depends on where this code is and what you want to happen. If it is in the UI layer - catch it and show a warning; if it's in the service layer - don't catch it at all - let it bubble. Just don't swallow the exception. If an exception occurs in most of the cases you should choose one of these:

    • log it and return
    • rethrow it (declare it to be thrown by the method)
    • construct a new exception by passing the current one in constructor
  4. Now, couldn't the above code also be a checked exception? I can try to recover the situation like this? Can I?
    It could've been. But nothing stops you from catching the unchecked exception as well

  5. Why do people add class Exception in the throws clause?
    Most often because people are lazy to consider what to catch and what to rethrow. Throwing Exception is a bad practice and should be avoided.

Alas, there is no single rule to let you determine when to catch, when to rethrow, when to use checked and when to use unchecked exceptions. I agree this causes much confusion and a lot of bad code. The general principle is stated by Bloch (you quoted a part of it). And the general principle is to rethrow an exception to the layer where you can handle it.

C# explicitly defining what exceptions are thrown

There is nothing equivalent in C#: The Trouble with Checked Exceptions

Other than documentation, there is no way to declare an interface to say "methodX() should throw this exception on error".



Related Topics



Leave a reply



Submit