24

I am having some problems with understanding the differences between checked and unchecked exceptions in Java.

  1. Firstly, checked exceptions are supposed to look for abnormalities during compile time. Examples provided in different sources cite database connectivity, file handling as some of them, while unchecked exceptions are supposed to look for errors on the programmer's part, like indexing beyond the range of an array, etc.

Shouldn't it be the other way round? I mean, database connectivity is done during run-time, right? Same goes for file-handling. You don't open a file-handle during compile time, so why a possible error on that is looked for during compile-time? On the other hand, indexing an array beyond its range is already done in the program, which can be checked during compile time (if the abnormal index is supplied by user during run-time, then it's okay for it to be a run-time problem). What am I missing here?

2 Secondly, how can RunTimeException, itself being unchecked, subclass Exception, which is checked? What does this signify?

I found an example in Herbert Schildt's book explaining the usage of checked exceptions:

class ThrowsDemo {
   public static char prompt(String str)
      throws java.io.IOException {
  System.out.print(str + ": ");
  return (char) System.in.read();
  }
  public static void main(String args[]) {
    char ch;
    try {
      ch = prompt("Enter a letter");
    }
    catch(java.io.IOException exc) {
     System.out.println("I/O exception occurred.");
     ch = 'X';
    }
    System.out.println("You pressed " + ch);
    }
}

Is the throws clause necessary here? Why can't I do it just normally with a try-catch statement like this (sorry I don't know how to simulate an IO Exception, so couldn't check it myself!):

class ThrowsDemo {
   public static char prompt(String str)  {
     System.out.print(str + ": ");
     return (char) System.in.read();
  }
  public static void main(String args[]) {
    char ch;
    try {
      ch = prompt("Enter a letter");
    }
    catch(java.io.IOException exc) {
     System.out.println("I/O exception occurred.");
     ch = 'X';
    }
    System.out.println("You pressed " + ch);
    }
}
SexyBeast
  • 7,913
  • 28
  • 108
  • 196
  • Possible duplicate of [Difference between Unchecked exception or runtime exception](http://stackoverflow.com/questions/2699580/difference-between-unchecked-exception-or-runtime-exception) – Tom Dec 23 '15 at 13:28
  • Checked exceptions are *not* to detect compile-time problems. That's the purpose of compiler errors. – erickson Mar 24 '16 at 15:27

8 Answers8

30

CheckedException needs to be handled by the caller, Unchecked exception don't.

So, when you design your application you should take in mind what kind of exceptional situation you are managing.

For example, if you design a validation method that checks the validity of some user input, then you know that the caller must check the validation exception and display the errors to the user in a nice looking way. This should be a checked exception.

Or, for those exceptional conditions that can be recovered: imagine you have a load balancer and you want notify the caller that one of the "n" servers is down, so the caller must recover the incident re-routing the message to another server; this should be a checked exception, because it is crucial that the caller (client) tries to recover the error, and don't just let the error to break the program flow.

Instead, there are many conditions that should not happen, and/or should instead break the program. For example, a programming error (like division by zero, null pointer exception), a wrong usage of an API (IllegalStateException, OperationNotSupportedException), an hardware crash, or just some minor situation that are not recoverable (lost connection to a server), or a doomsday :-) ; in those cases, the normal handling is to let the exception reach the most outer block of your code that displays to the user that an unpredictable error has occurred and the application can't do nothing to continue. It's a a fatal condition, so the only thing you can do is to print it to the logs or showing it to the user in the user interface. In those cases, catching the exception is wrong, because, after catching the exception you need to manually stop the program to avoid further damages; so it could be better to let some kind of exception "hit the fan" :)

For those reasons there are some exceptions that are Unchecked also in the JRE: OutOfMemoryError (unrecoverable), NullPointerException (it's a bug that needs to be fixed), ArrayIndexOutOfBoundsException (another bug example), and so on.

I personally think that also SQLException should be unchecked, since it denotes a bug in the program, or a connection problem to the database. But there are many examples where you get exception that you really don't have any clue in how to manage (RemoteException).

The best way to handle exceptions are: if you can recover or manage the exception, handle it. Otherwise let the exception pass out; somebody else will need to handle. If you are the last "somebody else" and you don't know how to handle an exception, just display it (log or display in the UI).

Luigi R. Viggiano
  • 8,659
  • 7
  • 53
  • 66
  • Cool. Just a couple of questions, if there is an unrecoverable error, JVM will terminate it anyway. So what is the point of raising a run-time exception? Only to give a appropriate status message? I was under the impression that exceptions let you trap the error, do some brush-up work and let the program resume normally. And secondly, how can you 'recover' from a checked exception? What exactly do you mean by 'recover'? – SexyBeast Dec 23 '12 at 16:11
  • 2
    Not really. If there is a crash on the filesystem, your JVM may still run. I think that also if there is an OutOfMemoryError, the JVM doesn't stop: there are threads that are not requiring additional memory so they can continue, or some references may be freed later and the program may still continue to work properly. Raising a Runtime Exception means to say "this exception, usually you don't/cant'handle, but if you want, feel free". For example, if I have a designed a special computer that is able to mount new RAM chips into the machines, I can also handle the OutOfMemoryException! :) – Luigi R. Viggiano Dec 23 '12 at 16:17
  • By 'recover' I mean a scenario like this: you call a method which sends some message to a remote computer via a socket. If the connection drops temporarily, I may recover trying again for a couple of times before to give up. It's your choice to decide whether it is best to let the user retry manually or implement this 'recovery' logic in your software. If you are dealing with a user that can retry manually the 'not recovering' policy is probably the best. But if you are implementing a server running without user interaction, you must think if it's the case to recover temporary network failures – Luigi R. Viggiano Dec 23 '12 at 16:25
  • Okay, but in these case I can easily put the recovery code in the `catch` block, why does it need a `throws` clause? – SexyBeast Dec 23 '12 at 16:27
  • 1
    The throws clause is to oblige the developer to take into account the fact that there is an exception that should be managed. Is a "memento". If I make a validation framework who throws unchecked exception, then the programmer may forget to catch some validation exception... and have a bug. A checked exception force the programmer to do one of the two things: catch the exception and handle it, or let the exception pass over declaring the throws. It's just a "memento" to avoid the developer to forget to handle some cases that NEED to be handled. Unchecked exception don't need `throws` clause – Luigi R. Viggiano Dec 23 '12 at 16:33
  • Wow, that was neat. Thanks. Just another question how come the `Exception` class, which is `checked`, has **`RunTimeException`** as subclass even though the latter is `unchecked`? – SexyBeast Dec 23 '12 at 16:37
  • The magic is done in the compiler. At compile time your exception hierarchy is inspected, and if there is RuntimeException in the hierarchy it is treated as unchecked (so no `throws` clause is needed), otherwise the compiler refuses to compile until you put the `throws' clause or catch the exception. It's just a rule implemented in the compiler. It is possible to mess this mechanism up see: http://en.newinstance.it/2008/11/17/throwing-undeclared-checked-exceptions/ for the JVM there is no actual difference between checked and unchecked; this is implemented as language feature in the compiler – Luigi R. Viggiano Dec 23 '12 at 16:41
9
  1. you do not need to declare unchecked exceptions in a throws clause; but you must declare checked exceptions;
  2. RuntimeException and Error, and all of their subclasses (IllegalArgumentException, StackOverflowError etc), are unckecked exceptions; the fact that RuntimeException is unchecked, unlike other Throwable subclasses, is by design;
  3. there is no such thing as "compile time exceptions".

More generally, it is considered that unchecked exceptions are thrown in the event of either JVM errors or programmer errors. One famous such exception is NullPointerException, often abbreviated as NPE, which is a subclass of RuntimeException, and therefore unchecked.

Another very crucial difference between unchecked exceptions and checked exceptions is that within a try-catch block, if you want to catch unchecked exceptions, you must catch them explicitly.

Final note: if you have exception classes E1 and E2 and E2 extends E1, then catching and/or throwing E1 also catches/throws E2. This stands for both checked and unchecked exceptions. This has an implication on catch blocks: if you do differentiate between catching E2 and E1, you must catch E2 first.

For instance:

// IllegalArgumentException is unchecked, no need to declare it
public void illegal()
{
    throw new IllegalArgumentException("meh");
}

// IOException is a checked exception, it must be declared
public void ioerror()
    throws IOException
{
    throw new IOException("meh");
}

// Sample code using illegal(): if you want to catch IllegalArgumentException,
// you must do so explicitly. Not catching it is not considered an error
public void f()
{
    try {
        illegal();
    } catch (IllegalArgumentException e) { // Explicit catch!
        doSomething();
    }
}

I hope this makes things clearer...

fge
  • 119,121
  • 33
  • 254
  • 329
7
  1. No. All the exceptions happen at runtime. Checked exceptions are exceptions that force the caller to handle them or declare them. They are usually intended to signal recoverable errors, which are not caused by a programmer error (like a file not being there, or a network connectivity problem). Runtime exceptions are usually intended to signal non-recoverable errors. They don't force the caller to handle or declare them. And many of them indeed signal programming errors (like NullPointerException).

  2. Because that's how the JLS define an unchecked exception: an exception that is or extends RuntimeException, which itself extends Exception. Using a single inheritance root allows handlong every possible exception in a single catch clause.

Regarding your example: yes, the throws clause is mandatory, since IOException is a checked exception and that the code inside the method is susceptible to throw one.

JB Nizet
  • 678,734
  • 91
  • 1,224
  • 1,255
  • I don't understand, how can you check for validity of a file-handle during compile time? And why can't I do it with a normal `try-catch` statement? What does `throws` achieve here which `try-catch` can't? – SexyBeast Dec 23 '12 at 14:45
  • 1
    All the exceptions happen at runtime. That's the first words of my answer. There's no compile-time exception. That doesn't exist. `throws` signals that a method can throw an exception when it's called. `try/catch` catches an exception thrown by a called method. `throws` is like a "Danger! slippery ground" panel. `try/catch` is like "Wow, the ground is slippery. I'll take care of it". – JB Nizet Dec 23 '12 at 14:51
  • Then why can't I always use `try-catch` in place of `throws`? – SexyBeast Dec 23 '12 at 14:54
  • 1
    I don't know how to find another simpler example than that. If you're the ground cleaner, and want to warn other people about the slippery ground, you don't do it by making very small steps. You do it by placing a "Warning!" panel on the ground. That's what `throws` does. If you're a person walking on the ground, the "Danger" panel makes you aware that the ground is slippery and that you should make very small steps to avoid falling. That's what `try/catch` does: it handles the exceptional case by doing something specific. – JB Nizet Dec 23 '12 at 14:58
  • I really didn't understand the analogy. You say that `throws` gives some early warning that an abnormality may be happening soon. But `try-catch` itself always takes care of that. If there is an error, it acts accordingly, if not, acts normally. What significant gain do I earn by using `throws`? – SexyBeast Dec 23 '12 at 15:03
  • You don't really have the choice. Every checked exception MUST be declared in the throws clause. The compiler checks it. That's why they're called checked exceptions. The gain is that it makes the code more robust, because the caller of the method is also FORCED to either redeclare the exception, or catch it. So the exceptional case can't be neglected: you're forced to think about it and handle it, instead of ignoring it and let the disaster happen in production. – JB Nizet Dec 23 '12 at 15:07
  • But even with normal `try-catch`, the caller *is* catching a possible exception. So he is definitely not neglecting exceptional cases (otherwise why would he even use `try-catch`?), and is definitely forced to think about it and handle it..I know I am sounding a bit dumb probably, but please, I need to understand it! – SexyBeast Dec 23 '12 at 15:11
  • @Cupidvogel What the caller does is irrelevant: `prompt` **may throw `IOException`**, therefore it **must declare it**. That's how the specification wants it. What would you like instead? – Marko Topolnik Dec 23 '12 at 15:19
  • If you didn't have the source code of the `prompt()` method (because it's part of a library), if the javadoc of the method didn't talk about IOException at all, and if the compiler didn't tell you "Hey, you're calling prompt(), so you MUST handle IOException, because there's a chance that prompt throws an IOException", how would you know that such an exception can happen, and that you'd better handle it? You wouldn't know about it, so you wouldn't use `try/catch` arounf the call to `prompt()`, and the code would miserably fail when the exceptional case happens. – JB Nizet Dec 23 '12 at 15:20
  • Okay, so the main reason is that this is how the specs specify it. That being said, and assuming I know that this *may* throw `IOException` error, will the two methods differ in any way? – SexyBeast Dec 23 '12 at 15:25
  • 1
    Which two methods? There is only a single method. IOException MUST be declared in the throws clause of the method throwing it (`prompt()`). And the caller (`main()`) MUST catch it, or MUST declare it as well in its throws clause. You don't have the choice. If you don't do that, the compiler will refuse to compile your code. – JB Nizet Dec 23 '12 at 15:30
2

The compiler only makes sure a method can't throw a checked exception if it didn't declare it. It is a general belief that such checking by compiler should be done for the exceptions whose occurrence is outside programmer's control, such as the examples you cite (database connectivity, files missing, etc.). Unchecked exceptions are "not supposed to happen", so the compiler doesn't force you to declare them.

As for simulating IOException or any other, it is trivial:

throw new IOException();

In your example the prompt method may throw an IOException, that's why it needs to declare it. This has nothing to do with how you handle the exception at the point you call the method.

RuntimeException is a subclass of Exception to make it convenient to catch all exceptions with one catch Exception clause. This could have been designed differently; Java's exception class hierarchy is a mess.

Marko Topolnik
  • 195,646
  • 29
  • 319
  • 436
1

If you dont put throws clause in here then this error will occur

ThrowsDemo.java:5: unreported exception java.io.IOException; must be caught or d eclared to be thrown return (char) System.in.read();

so throws clause in necessary.

Abhishekkumar
  • 1,102
  • 8
  • 24
1

Five example of checked exception and unchecked exception.

Unchecked Exception
   -- NullPointerException
   -- ArrayIndexOutofBound
   -- IllegalArgument Exception
   -- ClassCastException
   -- IllegalStateException
   -- ConcurrentModificationException

Checked Exception Five Example
   -- FileNotFoundException
   -- ParseException
   -- ClassNotFoundException
   -- CloneNotSupportException
   -- SQLException
stackinfostack
  • 650
  • 2
  • 7
  • 12
0

Checked and unchecked exceptions

There are two types of exceptions: checked exceptions and unchecked exceptions. The main difference between checked and unchecked exception is that the checked exceptions are checked at compile-time while unchecked exceptions are checked at runtime.

Please read this article to get a clear idea.

Rahul
  • 2,431
  • 3
  • 35
  • 77
0

More Details

Use checked exceptions when the client code can take some useful recovery action based on information in exception. Use unchecked exception when client code cannot do anything. For example, convert your SQLException into another checked exception if the client code can recover from it and convert your SQLException into an unchecked (i.e. RuntimeException) exception, if the client code cannot do anything about it.