exception in Java

<b>Hierarchy of exceptions</b>
* java.lang.Object
    * java.lang.Throwable
        * java.lang.Error: This is runtime error actually. An error is fatal and should not be caught by the program. While it is legal to catch an error, it is not a good practice.
        * java.lang.Exception
            * java.lang.RuntimeException. Occurs during the execution of the program, hence they are also referred to as runtime exceptions. These exceptions are not checked while compiling the program; also known as Unchecked exceptions.  
           * Checked exceptions. Also known as compile-time exceptions as these exceptions are checked during the compilation process to confirm handled by the programmer or not. If not, then the system displays a compilation error. 

<b>Type of exceptions</b>
Type | Thrown by | Hierarchy | Recommeded to catch | Required to catch
----- | ----- | ----- | ----- | ----- 
Runtime exception | both the JVM and programmer code | RuntimeException or its subclasses | Yes | No
Checked exception | programmer code | Exception or its subclasses but not RuntimeException or its subclasses | Yes | Yes
Error | JVM | Error or its subclasses | No | No

<b>Checked exceptions</b>
Checked exception | Used when
----- | -----
java.text.ParseException | Converting a String to a number.
java.io.IOException<br>java.io.FileNotFound Exception<br>java.io.NotSerializable Exception | Dealing with IO and NIO.2 issues. IOException is the parent class. There are a number of subclasses. You can assume any java.io exception is checked.
java.sql.SQLException | Dealing with database issues. SQLException is the parent class. Again, you can assume any java.sql exception is checked.

<b>Runtime exceptions</b>
Runtime exception | Used when
----- | -----
java.lang.ArithmeticException | Thrown by the JVM when code attempts to divide by zero.
java.lang.ArrayStoreException | Trying to store the wrong data type in an array.
java.lang.ArrayIndexOutOfBoundsException | Trying to retrive a "box" that does not exist, by passing an index that is higher than the index of last "box", or negative.
java.lang.ClassCastException | Thrown by the JVM when an attempt is made to cast an object to a subclass of which it is not an instance.
java.lang.IllegalArgumentException | Thrown by the program to indicate that a method has been passed an illegal or inappropriate argument.
java.lang.IllegalStateException<br>java.lang.UnsupportedOperationException | Attempting to run an invalid operation in collections and concurrency.
java.lang.NegativeArraySizeException | Trying to initialize an array with a negative length. 
java.lang.NullPointerException | Thrown by the JVM when there is a null reference where an object is required.
java.lang.NumberFormatException | Thrown to indicate that the application has attempted to convert a string to one of the numeric types, but that the string does not have the appropriate format. 
java.time.DateTimeException | Receiving an invalid format string for a date.
java.util.MissingResourceException | Trying to access a key or resource bundle that does not exist.

When creating your own exception, you need to decide whether it should be a checked or unchecked exception. While you can extend any exception class, it is most common to extend Exception (for checked) or RuntimeException (for unchecked.)
Always throw an Exception (never a Throwable). You generally don't catch Throwable either, but you can. Throwable is the superclass to Exception and Error, so you would catch Throwable if you wanted to not only catch Exceptions but Errors, that's the point in having it. The thing is, Errors are generally things which a normal application wouldn't and shouldn't catch, so just use Exception unless you have a specific reason to use Throwable.
```
public class CannotSwimException extends Exception {
    public CannotSwimException() {
        super();
    }
    public CannotSwimException(Exception e) {
        super(e);
    }
    public CannotSwimException(String message) {
        super(message);
    }
}
```
When calling a method which throwing a checked exception, the calling method should declare or handle that check exception other wise compilation fails.
```
class Main {
    public static void main(String args[]) throws Exception // need throws Exception cause fun() did that
    {
        new Main().fun();
    }
    
    public void fun() throws Exception {
        System.out.print(1);
    }
}
```