Exceptions are thrown by a program when something goes wrong! It is Java’s way of telling you something has happened that it wasn’t expecting and it doesn’t know how to handle the problem. So it just tells you, usually by printing out a stack trace of the error.
Exceptions fall into two main categories - checked exceptions and unchecked exceptions.
Both checked and unchecked exceptions are throw-able, and are all classes that extend from the super-class “Throwable”.
As you can see by the diagram above, unchecked exceptions ( exceptions not checked at compile time) are “RuntimeException” and its sub-classes, and “Error” and its sub-classes. Unchecked exceptions are exceptions generally caused internally to the program and are generally caused by poor programming, they are exceptions that a program can not reasonably be expected to recover from, but in some instances are (demonstrated in diagram below).
Some common examples of Runtime Exceptions include: Arithmetic exceptions - when dividing by zero, when attempting to access an object through a null reference (NullPointerException), and when attempting to access an array element that doesn’t exist (ArrayIndexOutofboundsException).
Here are some code examples: and some methods of dealing with the above run-time Exceptions: In the above example you will notice that in some cases you do not actually have to throw or handle a run-time exception. To prevent the ArrayIndexOutOfBoundsException, assuming we are attempting to get the last element in the array, I used a simple if statement to make sure that if the variable “num” was larger than the length of the array, then to set the value of num to the value in the last element of the array.
Checked exceptions are exceptions that are checked during compilation of a program, and require a programmer to declare them either using a throws clause in a method signature or by declaring them in a try-catch statement. They are generally recoverable problems which are caused externally to the program: e.g. reading data from a file, hard-drive disconnected, or a database being offline.
If a throws clause is used then the Exception does not have to be handled in the method body and will be passed back to the calling program, where it can either be handled or thrown further to its calling program, until it reaches the main method, where if it isn’t handled the program will stop running. This is known as the “Catch or Declare” rule.
Here is an example, assuming incorrect syntax is used in an SQL SELECT query: In the above example I am attempting to contact an SQL database, this could potentially cause an SQLException which is a sub-class of Exception and NOT a sub-class of RuntimeException or Error. So it must be handled or declared. In this instance I decided to throw the exception to the calling method main(), where I handled it using the try-catch statement, which prints a stack trace log containing information of what specifically is wrong and on what line of code the error occurs.
These are Exceptions that occur that should not be handled or declared at all. Errors are usually rare and are generally irrecoverable. One example is the “StackOverflowError” exception which is caused when a method calls itself causing an infinite loop of declaring local variables which sit on the stack ( a space in memory reserved for variables). During an infinitely recursive method call these method declarations will eventually fill up the stack and cause the program to run out of memory. The JVM is smart enough to spot when code is calling itself recursively and will throw a StackOverflowError.