Things every Java developer must know about Exception handling

Exceptions are one of the most misunderstood (and misused) features of the Java programming language. This article describes the absolute minimum every Java developer must know about exceptions. It assumes that the reader is somewhat familiar with Java.

Historical Perspective

Back in the heyday of the “C” programming language, it was customary to return values such as -1 or NULL from functions to indicate errors. You can easily see why this isn’t a great idea – developers had to check and track possible return values and their meanings: a return value of 2 might indicate “host is down” error in library A, whereas in library B, it could mean “illegal filename”.

Attempts were made to standardize error checking by expecting functions to set a global variable with a defined value.


James Gosling and other designers of the language felt that this approach would go against the design goals of Java. They wanted:

  1. a cleaner, robust and portable approach
  2. built in language support for error checking and handling.

Luckily, they didn’t have to look too far. The inspiration for handling errors came from a very fine language of the 60’s: LISP.

Exception Handling

So what is exception handling? It is unconventional but simple concept: if an error is encountered in a program, halt the normal execution and transfer control to a section specified by the programmer. Let’s look at an example:

try {
   f = new File("list.txt"); //Will cause an error if the file is not found...
   f.write("another item for the list");
} catch (FileNotFoundException fnfe) { // ... and transfer control to this section on error.
   // Do something with the error: notify user or try reading another location, etc


Exceptions are exceptional conditions that violate some kind of a “contract” during program execution. They can be thrown by the language itself (e.g. use a null reference where an object is required) or by the developers of program or API (e.g. passing date in British format instead of American). Some examples of exceptions are:

  • Accessing index outside the bounds of an array
  • Divide by 0
  • Programmer defined contract: Invalid SQL or JSON format

Exceptions disrupt the normal program flow. Instead of executing the next instruction in the sequence, the control is transferred to the Java Virtual Machine (JVM) which tries to find an appropriate exception handler in the program and transfer control to it (hence disrupting the normal program flow).

Checked and Unchecked Exceptions

Before we look at the exception classes in Java, let’s understand the two categories of exceptions in Java:

Checked exceptions – You must check and handle these in your program. For example, if you are using an API that has a method which declares that it could throw a checked exception, you must catch the exception each time you call that method. If you don’t, the compiler will notice and your program will not compile. The designers of the Java wanted to encourage developers to use checked exceptions in situations from which programs may wish to recover: for example, if the host is down, the program may wish to try another address.

Unchecked exceptions on the other hand are not required to be handled or caught in the program. For example, if a method could throw unchecked exceptions, the caller of the method is not required to handle or catch the exceptions.

Remember: Checked exceptions are mild and normally programs wish to recover. They must be caught and this rule is enforced by the compiler. The compiler doesn’t care whether you do or do not catch unchecked exceptions.

Many people find dichotomy between checked and unchecked exceptions confusing and counter-intuitive. Discussing the arguments from both sides are beyond the scope of this post.

Parent of all exception classes: Throwable

All exceptions in Java descend (subclass) from Throwable . It has two direct children:

  1. Exception
  2. Error

Error and its sub-classes are used  for serious errors from which programs are not expected to recover,  i.e. unchecked exception.

Exception and its sub-classes are used for mild errors from which programs may wish to recover, i.e. checked exception. Right? Well, there is a twist. There is just one sub-class which is different, that is, unlike it’s parent the Exception class, it is unchecked. It’s called the RuntimeException.



Checked exception classes (mostly): Exception

Exception and its sub-classes must be caught and as such they force the programmer to think (and hopefully) deal with the situation. It is a signal that something didn’t go as intended along with some information about what went wrong, and that “someone” should do something about it. (e.g. car’s dashboard indicating that the battery needs service).

According to official documentation:

These are exceptional conditions that a well-written application should anticipate and recover from. For example, suppose an application prompts a user for an input file name,  [..] But sometimes the user supplies the name of a nonexistent file, and the constructor throws A well-written program will catch this exception and notify the user of the mistake, possibly prompting for a corrected file name.

Source: The Java Tutorials


RuntimeExceptions are used to indicate programming errors, most commonly violation of some established contract. They make it impossible to continue further execution.

For example, the contract says that the array index mustn’t go past [array_length – 1]. If you do it, bam, you get a RuntimeException. A real world analogy would be pumping diesel into a gasoline car: the unwritten contract says that you must not do it. There are no  signals, just the white smoke before the car comes to a grinding halt after a while. The message: it was your fault and could’ve been prevented by being smarter in the first place.

These are exceptional conditions that are internal to the application, and that the application usually cannot anticipate or recover from. These usually indicate programming bugs, such as logic errors or improper use of an API.

Source: The Java Tutorials


These exceptional circumstances are like “act-of-god” events. Going back to our previous analogy, if a large scale alien invasion were to happen, there is nothing you could do your protect your car, or yourself (unless your last name is Ripley). In Software world, this amounts to the disk dying while you are in the process of reading a file from it. The bottom line is that you should not design your program to handle Errors since something has gone wrong in the grand scheme of things that are beyond your control.

These are exceptional conditions that are external to the application, and that the application usually cannot anticipate or recover from. For example, suppose that an application successfully opens a file for input, but is unable to read the file because of a hardware or system malfunction.

Source: The Java Tutorials

It’s not so black and white

Checked exceptions are often abused in Java. While Java forces developers to catch unchecked exceptions, it cannot force them to handle these exceptions. It’s not hard to find statements like this even in well written programs:

try {
   Object obj = ...
   Set<String> set = ...
   // perform set operations
} catch (Exception e) {
   // do nothing

Should you ever catch Runtime Exceptions?

What’s the point of catching RuntimeExceptions if the condition is irrecoverable? After all, if you were catching every possible run-time exception, your program will be cluttered with exception handling code everywhere.

RuntimeExceptions are rare errors that could be prevented by fixing your code in the first place. For example, dividing a number by 0 will generate a run time exception, ArithmeticException. But rather than catching the error, you could modify your program to check the arguments for division function and make sure that the denominator > 0. If it is not, we can halt further execution or even dare to throw a exception of our own: IllegalArgumentException.

In this case, the program got away by verifying the input parameters instead of catching RuntimeExceptions.

So when is it OK for an application to catch RuntimeExceptions?

A while back, I architected a high-performance traffic director with the goal of operating in the proximity of 10,000 transactions per seconds (TPS). The project had a very high availability criteria and one of the requirement was that it “must-never-exit”.

The director performs minimum amount of processing on each transaction before passing it further. Transactions came in two flavours, call them: A and B. We were only interested in transactions of type A. We had a transactions handler to process type A. Naturally, it “choked” run time exceptions when we passed in transactions of type B. The solution? Create a function and pass it every single transaction. If it returned true, we continued to further processing. Otherwise, we simply ignored the transaction, and continued onto the next one.

boolean checkFormat(Transaction t) {
//return true if the t is of type A. false otherwise.

This worked well, except…..

… the analysis showed that this function returned false only once a year. The reason, 99.99999999999999% transactions were of type A. Yet, we were subjecting every single transaction to be checked. This does not sound so bad, but due to the nature of transactions, the only way to differentiate was by doing expensive String comparison on various fields.

When this finding was brought to my knowledge, I immediately had the `checkFormat(…)` function removed and instead let the handler do it’s course and throw RuntimeException upon encountering transaction of type, B. When the exception gets thrown once a year, we catch it, log it and move onto the next transaction. The result: improvement in performance, and room to squeeze in additional calculations.


Exceptions in java are either checked or unchecked. Checked exceptions must be caught in the program otherwise the compiler will complain. While Java encourages developers to follow certain guidelines when it comes to exception handling, there aren’t any hard and fast rules and the rules are often bent.


Thank you for reading my blog. Let's connect on LinkedIn.

Tagged with: ,
Posted in Java
30 comments on “Things every Java developer must know about Exception handling
  1. Anonymous says:

    What did I just waste my time on?

    • Cory Gross says:

      Did you read the entire article… I thought it was rather useful insight, particularly at the end. If you already knew all of this, did you not realize that before reading the entire thing?

  2. Cayman says:

    Good post. OutOfMemory is another RuntimeEcxeption that should be caught in high availability applications invoking garbage collector for clean up.

  3. traxtech says:

    And that’s just one example amongst thousands of others :( is also quite commonly annoying.

  4. pjungwir says:

    I think it’s normal to catch RuntimeExceptions at a high level in your outer loop so you can log it, email it, or whatever, and not let your process die. This is what servlet containers like Tomcat are doing. I agree that catching them elsewhere raises suspicions.
    The author’s example seems fine, provided they can distinguish an exception-from-a-B-transaction vs an exception-from-a-program-bug. If I were him, I’d keep that checkFormat method, but only call it when I catch a RuntimeException, to see if it’s something to worry about or not.
    I was pleased that the author appears to have tested the performance of both approaches and is making a decision based on real numbers.

  5. You can invoke GC (which generally speaking, you should not), but this doesn’t guarantee it will clean up anything. OOM exceptions should be considered terminal, as they are an Error, not an Exception.

  6. aardvark179 says:

    I strongly agree that runtime exceptions are the right way to go for certain rare events, see for example the new Java 8 addExact and multiplyExact methods which throw exceptions on overflows. These will not happen often but making them an exception allows implementers of languages with numeric type promotion to remove their own checks, and for the JIT to optimise the entire exception away in most cases.

  7. stickfigure says:

    Sorry, this is not going to be gentle.
    This post is clearly written by someone who is new to Java, and starts with the antique assumption that the runtime/checked exception dichotomy is a good idea. After nearly two decades of experience, programmers and language designers have resoundingly voted this language design feature to be a failure. A little bit of experience catching idiotic exceptions like UnsupportedEncodingException and you start to see why. But it goes deeper than just bad design in the standard libraries – checked exceptions fundamentally violate interface encapsulation – try throwing a meaningful exception through Runnable or Iterator. The net result is stacktraces with dozens of wrapped exceptions that destroy any hope of meaningfully handling known error conditions.
    Stop it. JUST STOP IT. Checked exceptions have wasted hundreds of hours of my time, not just writing lame wrappers so that I don’t have to type try/catch on every line of code, but also by making debugging and error handling five times more painful than it should be.
    If you’re still touting checked exceptions in 2013, you are part of the problem. Stop it. Java needs to evolve, and your fresh-from-1995 opinion is not helping.
    TL;DR: Of course you should catch RuntimeExceptions. There should be no other kind of exception.

    • pifflesnort says:

      > checked exceptions fundamentally violate interface encapsulation
      You have that backwards. Unchecked exceptions will blithely and without warning completely explode your stack. They’re the Atomic Goto.
      The only way to know whether you’re going to get one is to check the documentation, where you can only hope that the API author — and the author of every API he calls — has actually documented the exceptions that get thrown, because the compiler will be no help whatsoever, and god forbid an API start throwing an exception later.
      > … try throwing a meaningful exception through Runnable or Iterator.
      If you pass around an object that conforms to Iterator, but throw an exception within it, __YOU’RE BREAKING THE API CONTRACT.__
      Anyone that relies on the API contract of the Iterator class could have their state completely walloped by the Atomic Goto you inserted with a runtime exception.
      > Stop it. JUST STOP IT. Checked exceptions have wasted hundreds of hours of my time, not just writing lame wrappers so that I don’t have to type try/catch on every line of code, but also by making debugging and error handling five times more painful than it should be.
      This makes no sense, because more work is required without checked exceptions.
      Without checked exceptions:
      – You must check the API docs for every line of code you write to see if it will throw an exception, and if so, what types.
      – If it throws an exception, you must either add a try/catch block to handle the error appropriately (or wrap it in a new exception type), or you must add documentation to your method to declare that it will bubble up an exception, and of what type.
      – If new exception types are thrown by underlying code, nothing tells you until your application explodes.
      With checked exceptions:
      – The compiler tells you what exceptions code throws, and of what type.
      – If it throws an exception, you must either add a try/catch block to handle the error appropriately, or declare it in the method prototype. The IDE will do both of these things for you.
      – If new exception types are thrown by underlying code, the compiler will warn you.
      > If you’re still touting checked exceptions in 2013, you are part of the problem. Stop it. Java needs to evolve, and your fresh-from-1995 opinion is not helping.
      Stop advocating broken API design and ignorance of API invariants.

    • Teckla says:

      “This post is clearly written by someone who is new to Java”
      That was uncalled for. But, since you’ve decided to immediately call into question people’s credentials, let me start with mine. I’ve done a little over 30 years of software development, and in that time I’ve programmed in no less than three assembly languages, several BASICs, Pascal, C, C++, JavaScript, dabbled with C#, dabbled with Go, dabbled with Python, been subjected to some Perl and PHP, etc. I’m not God’s Gift to Software Development, but I think I have enough experience that my opinion on this matter shouldn’t be discarded as uninformed.
      “and starts with the antique assumption that the runtime/checked exception dichotomy is a good idea.”
      I hope you’re aware that you’re begging the question. In any case, I think checked exceptions are fantastic.
      1. The “burden” of dealing with them is minuscule, especially when using modern IDEs. It takes just a few clicks or key presses to add try/catch blocks or re-throw exceptions as necessary. You don’t even have to waste time looking up documentation (which may be wrong or even nonexistent). Your tool-chain (IDE and compiler) handles the mundane details for you.
      2. It forces developers, who are often hurried, and who often make mistakes, to think about things that could go wrong, and deal with them (one way or another). Oh, sure, you see plenty of “catch (Exception e)” style abuses, but that particular “code smell” is so strong (i.e., easily identified) that it can make code reviews (personal and public) easier. Code reviews in languages with only unchecked exceptions are much more difficult and time consuming.
      3. Checked exceptions speeds development. Much less time is spent reading and re-reading API documentation to make sure you’ve caught all the possible exceptions that might be thrown (so that you can do things like produce meaningful error messages or log entries based on the exception thrown).
      4. Unchecked exceptions are a production run-time nightmare. My anecdotal but extensive experience is that languages with only unchecked exceptions cause far too many costly (in both time and money) production headaches. Never, ever defer until run-time, errors that can be caught at compile-time! Admittedly, it could be that my application domain colors my opinion here (I work on large systems, not small systems).
      The best argument I’ve heard against checked exceptions is that they “bloat the code”. It’s true: checked exceptions requires more code. But I’m writing code, not poetry. My job is to get the implementation right (which checked exceptions help me do) and to write reliable and robust software. Developers who put more emphasis on writing pretty code (sorry, “highly expressive”) might want to consider becoming artists instead, where they can fashion “pretty” creations to their heart’s content.

  8. laksjdf says:

    i want my 12 volts!!

  9. jhdevos says:

    Of course, there are also the RuntimeExceptions that should really have been just Exceptions. These are often thrown by libraries where new features required exceptions to be thrown, but they couldn’t be checked exceptions because the interface had to remain backwards compatible…
    Or, of course, libraries written by people who just don’t like checked exceptions at all.

  10. Grant says:

    Java is flawed by design. I feel sorry for people who are still using it. There are much better alternatives like .NET.

    • Grant says:

      Not to mention it is slow as hell. I can only imagine the pain the author had to go through to write a java program for handling “10,000 transactions per seconds”!

      • 10kloc says:

        >> Not to mention it is slow as hell.
        Not necessarily. In most cases, the code can be optimized by the compiler to be on par with C/C++ code or even faster. The “stop-the-world” garbage collectors do cause slight performance trade-offs, but coming from a C++ background, I would much rather have automatic garbage collection than code reviewing and code reviewing to discover and eliminate all memory leakages. While processors are not doubling their speeds every 18 months, computers are still getting faster and faster. Even if your argument was true, I’m willing to take a slight performance hit over flexibility.

        >> pain the author had to go through to write a java program for handling “10,000 transactions per seconds”!

        Useless and ambiguous argument. Which stage of the software development are you referring to: architecting, coding, production? I find architecting and writing Java is fun. Not to mention the plethora of well tested libraries and frameworks which ship with JDK make my life easier.

        Thanks for posting.

      • david says:

        “Java is flawed by design. I feel sorry for people who are still using it. There are much better alternatives like .NET. Not to mention it is slow as hell.”

        Obvious troll is obvious!

    • GrantISARETARD says:

      Grant you are a retarded loser. It’s .NET that’s flawed. Still clinging to exes, dlls and com components. LOL like it’s 1990.

  11. Smoyer says:

    I’d love to be able to say I never have to catch RuntimeExceptions, but that would require that library and framework writers actually use checked exceptions when they should. The best example I can think of (and one that a JEE developer who uses JPA should be intimately familiar with) is that that the getSingleResult() method of the Query object in JPA throws RuntimeExceptions if zero or more than one result is returned.

    • Suresh says:

      The funny thing is, in almost any discussion about exception handling in Java, I hear the opposite complaint – too many APIs throw checked exceptions. I’ve been leaning more and more to liking it when APIs force consumers to at least be aware of known error conditions.
      Scala’s Option type is another example of this – I’ve watched people be sort of annoyed by it at first, but it tends to really improve the reliability and overall quality of the code when it is used properly.

      • lucian1900 says:

        Scala’s Option is a monad, so it’s very easy to chain several actions and safely decide if they all succeeded or failed. It doesn’t compare with checked exceptions at all.

  12. Uchikoma says:

    Runtime exceptions can turn into ugly production problems. I prefer a combination of Validation, Success/Failure, Some/None and checked exceptions.
    Runtime exceptions can turn into ugly production problems. I prefer a combination of Validation, Success/Failure, Some/None and checked exceptions.

  13. Ajinkya says:

    Before reading full article, I thought another blah-blah but after reading it I can say, it does offer some insight. In real world there are many situation,when you want to catch RuntimeException.

  14. […] said Operations Manager. Rob rushed back to the office and discovered that an uncaught run-time exception on a rare malformed request had brought the system down. The system was single point of failure. […]

  15. It was looking for an article explaining the principle of exception handling in Java and the differences between checked and unchecked exception. This is the perfect match!

    For the very first time, I reblog something on :)

Leave a Reply

Fill in your details below or click an icon to log in: Logo

You are commenting using your account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s


Get every new post delivered to your Inbox.

Join 31 other followers

%d bloggers like this: