1. Throw exceptions that are relevant to the interface
    – A function should throw exceptions that are relevant to its interface
    Example: java.io.FileInputStream.FileInputStream(String name) throws FileNotFoundException
    – The above code is used for opening a file on disk for reading bytes
    – The given constructor may throw a FileNotFoundException and not IndexOutOfBoundsException that is completely irrelevant to the code
    – Developers should make sure to throw exceptions that are relevant to the interface
  2. The reason for exception should be specified
    – The exception should always specify what caused them to occur
    – Exceptions can be handled in either of the following two ways:
    – Generating a separate exception for each and every event
    – Creating a generic exception and mentioning what caused that exception
    – The best practice is to use an exception class when handling specifically with separate code
    – Use a single generic exception class for handling exceptions in a default way