Introduction

Exception is an unwanted or unexpected event, which occurs during the execution of a program i.e at run time, that disrupts the normal flow of the program’s instructions. Exception indicates conditions that a reasonable application might try to handle gracefully. An Error indicates serious problem that a reasonable application should not try to catch.

All exception and errors types are sub classes of class Throwable. One branch is headed by Exception. Another branch, Error are used by the Java run-time system(JVM) to indicate errors having to do with the run-time environment itself (JRE). Below figure shows the exception hierarchy

Error occurs at run-time and Exception can happen either at compile time or run-time. Exception can be either Checked or Unchecked.

 

Exception Keywords

Keywords for exception handling are

  • throw: To generate exception explicitly in code use throw keyword. This keyword is used to throw exception to the runtime to handle it.
    public int getScore(String playerFile) throws FileNotFoundException {
      if(!isFilenameValid(playerFile)) {
         throw new IllegalArgumentException("Filename invalid!");
      }
      
      // Rest of the code
    }
  • throws: To throw any exception in a method and not handle it, use throws keyword in method signature to let caller program know the exceptions that might be thrown by the method. The caller method might handle these exceptions or propagate it to it’s caller method using throws keyword.
    public int getScore(String playerFile) throws FileNotFoundException {
      Scanner contents = new Scanner(new File(playerFile));
      return Integer.parseInt(contents.nextLine());
    }
  • try-catch: Use try-catch block for handling exception. try is the start of the block and catch is at the end of try block to handle the exceptions. We can have multiple catch blocks with a try and try-catch block can be nested also.
    public int getScore(String playerFile) {
      try {
        Scanner contents = new Scanner(new File(playerFile));
        return Integer.parseInt(contents.nextLine());
      } 
      catch (FileNotFoundException noFile) {
        throw new IllegalArgumentException("File not found");
      }
    }
  • finally: finally block is optional and can be used only with try-catch block. Since exception halts the process of execution, we might have some resources open that will not get closed, so we can use finally block. finally block gets executed always, whether exception occurred or not.
    public int getScore(String playerFile) throws FileNotFoundException {
      Scanner contents = null;
      try {
        contents = new Scanner(new File(playerFile));
        return Integer.parseInt(contents.nextLine());
      } finally {
        if (contents != null) {
          contents.close();
        }
      }
    }

     

 

Exceptions Types

There are two types of exceptions

  • Checked exceptions: Checked exceptions are exceptions that compiler requires us to handle. It is checked at compile time. If some code within a method throws a checked exception, then the method must either handle the exception or it must specify the exception using throws keyword. If these exceptions are not handled/declared in the program, you will get compilation error.In the below example, FileReader() throws a checked exception FileNotFoundException. readLine() and close() throw checked exception IOException. main() need to specify list of exceptions using throws, or use try-catch block. In the below example throws is used to pass the exception to calling method. Since FileNotFoundException is a subclass of IOException, we can just specify IOException in the throws list.
    class Main { 
    
      public static void main(String[] args) throws IOException { 
    
        FileReader file = new FileReader("C:\\test\\exception.txt"); 
        BufferedReader fileInput = new BufferedReader(file); 
        
        // Print lines of file
        for (int counter = 0; counter < 3; counter++) 
          System.out.println(fileInput.readLine()); 
        
        fileInput.close(); 
      } 
    }
  • Unchecked Exception: Runtime Exceptions are also known as Unchecked Exceptions. These exceptions are not checked at compile-time but it’s the responsibility of the programmer to handle these exceptions and provide a safe exit. For example, ArithmeticException, NullPointerException, ArrayIndexOutOfBoundsException etc. Compiler will never force you to catch such exception or force you to declare it in the method using throws keyword.If we create an exception that extends RuntimeException, it will be unchecked; otherwise, it will be checked. Below example compiles fine, but it throws ArithmeticException during runtime. The compiler allows it to compile, because ArithmeticException is an unchecked exception.
    class Main { 
      public static void main(String args[]) { 
        int x = 0; 
        int y = 10; 
        int z = y/x; 
      } 
    }

     

Custom Exceptions

Other then built-in exceptions, custom exceptions can be defined to suit the need. A user-defined exception must extend Exception class. The exception is thrown using throw keyword.

class MyException extends Exception{ 
  String msg;
  
  MyException(String s) {
    msg=s;
  }
  
  public String toString(){
    return ("Exception Occurred: " + msg);
  }
}

class Main{
  public static void main(String args[]){
   
    try{
      System.out.println("Start of try block");
      throw new MyException(“Error Message");
    }
    catch(MyException exp){
      System.out.println("Catch Block");
      System.out.println(exp);
    }
  }
}