throw and throws In Java

throw and throws In Java | In the introduction of Exception Handling, we have seen various concepts including exception hierarchy, Checked vs Unchecked Exception, and Fully Checked vs Partially Checked Exception. Later we discussed how to handle the exception using the try-catch-finally block with different test cases.

throw keyword in Java

public class Test {
   public static void main(String[] args) {
      System.out.println(10/0);
   }
}

Exception in thread “main” java.lang.ArithmeticException: / by zero
at Test.main(Test.java:3)

public class Test {
   public static void main(String[] args) {
      throw new ArithmeticException("divided by zero");
   }
}
  • throw:- Hand over our created exception object to the JVM manually.
  • new ArithmeticException(“divided by zero”):- Creation of ArithmeticException object explicitly.

Sometimes we can create exception objects explicitly & we can hand them over to the JVM manually. For that, we have to use the throw keyword. Hence, the main objective of the thread keyword:- to hand over our created exception object to the JVM manually.

The results of the above 2 programs are the same:-

  • In the 1st program:- In this case, the main method is responsible for creating an exception object and handing it over to the JVM.
  • In 2nd program:- In this case, the programmer creates an exception object explicitly & hands it over to the JVM manually.

The throw keyword is best used for user-defined exceptions or customized exceptions but not for pre-defined exceptions.

withdraw(double amount) {
   if (amount > balance) {
      throw new InsufficientFundsException();
   }
}

Case-1:- Before throwing the exception object, it must be initialized.

public class Test {
   static ArithmeticException e = new ArithmeticException();
   public static void main(String[] args) {
      throw e;
   }
}
public class Test {
   static ArithmeticException e;
   public static void main(String[] args) {
      throw e;
   }
}

We are trying to throw variable “a” which is not initialized in the program. By default static reference variables contain null.

Case-2:- After the throw statement, we are not allowed to write any statement directly otherwise we will get compile time error:- unreachable statement.

// valid
public class Test {
   public static void main(String[] args) {
      System.out.println(10/0);
      System.out.println("Hello");
   }
}
// compile time error
public class Test {
   public static void main(String[] args) {
      throw new ArithmeticException("/ by zero");
      System.out.println("Hello");
   }
}

In 1st program, just by seeing the syntax compiler doesn’t know System.out.println(10/0) will throw any error. At runtime due to 10/0, we will get ArithmeticException.

But in 2nd program, just by seeing the syntax throw new ... the compiler knows that this line will throw an exception & remaining line will never executed. Hence we will get the compile time error:- unreachable statement.

Case-3:- We can use the throw keyword only for Throwable types. If we are trying to use it for a normal Java object then we will get compile time error:- incompatible types.

public class Test {
   public static void main(String[] args) {
      throw new Test();
   }
}
public class Test extends RuntimeException {
   public static void main(String[] args) {
      throw new Test();
   }
}

throws Keyword In Java

import java.io.*;
public class Test {
   public static void main(String[] args) {
      PrintWriter pw = new PrintWriter("abc.txt");
      pw.println("Hello");
   }
}

In our program, if there is a possibility of raising a checked exception then we must handle that checked exception otherwise we will get compile time error:- unreported exception Xxx; must be caught or declared to be thrown.

public class Test {
   public static void main(String[] args) {
      Thread.sleep(1000); // 1 sec
   }
}

We can handle this compile time error:-

  1. By using try-catch
  2. By using the throws keyword

Handling exceptions using try-catch

public class Test {
   public static void main(String[] args) {
      try {
         Thread.sleep(1000); // 1 sec
      } catch (InterruptedException e) {}
   }
}

Compiler don’t worry what code we have written in the catch block. If we just check whether the Thread.sleep(1000) is inside the try block or not.

Handling Exception using the throws keyword

We can use the throws keyword to delegate the responsibility of exception handling to the caller (it may be another method or JVM) then the caller method is responsible for handling that exception.

public class Test {
   public static void main(String[] args) 
       throws InterruptedException {
      Thread.sleep(1000); // 1 sec
   }
}

Conclusion on throws:-

  • throws keyword is required only for checked exceptions & the use of the throws keyword on unchecked exceptions has no impact.
  • The throws keyword is required only to convince the compiler & the use of the throws keyword doesn’t prevent abnormal termination of the program.
public class Test {
   public static void main(String[] args) throws InterruptedException {
      m1();
   }
   public static void m1() throws InterruptedException {
      m2();
   }
   public static void m2() throws InterruptedException {
      Thread.sleep(1000); // 1 sec
      System.out.println("m2");
   }
}

In the above program if we remove at least one throws statement then the code won’t compile. If there is a chance of raising a checked exception in the m1() method then the m1() method also must handle it.

public class Test {
   public static void main(String[] args) throws InterruptedException {
      m1();
   }
   public static void m1() {
      m2();
   }
   public static void m2() throws InterruptedException {
      Thread.sleep(1000); // 1 sec
      System.out.println("m2");
   }
}
public class Test {
   public static void main(String[] args) throws InterruptedException { // place1
      m1();
   }
   public static void m1() {  // place2
      Thread.sleep(1000); 
      System.out.println("m1");
   }
}

// Compile-time error at place-2.

throws keyword Summary

  • We can use it to delegate the responsibility of exception handling to the caller (It may be method or JVM).
  • It is required only for checked exceptions and usage of the throws keyword for unchecked exceptions has no impact.
  • It requires only to convince the compiler and usage of throws doesn’t prevent abnormal termination of the program.

It is recommended to use the try-catch block over the throws keyword.

Case 1:- We can use the throws keyword for methods & constructors but not for classes.

public class Test { 
   Test() throws Exception {} // valid
   public static void main(String[] args) throws Exception {} // valid
}
public class Test throws Exception {} // invalid

Case 2:- We can use the throws keyword only for throwable types. If we are trying to use it for normal Java classes then we will get compile time error:- incompatible types.

public class Test {
   public static void main(String[] args) throws Test {}
}
// valid
public class Test extends RuntimeException {
   public static void main(String[] args) throws Test {}
}

Case 3:- If the program throws unchecked exceptions either manually or by the JVM, we must handle unchecked exceptions.

public class Test {
   public static void main(String[] args) {
      throw new Exception();// checked exception
   }
}
public class Test {
   public static void main(String[] args) {
      throw new Error();// unchecked exception
   }
}

Case 4:- Within the try block if there is no chance of raising an exception then we can’t write the catch block for that exception otherwise we will get compile time error:- Exception Xxx is never thrown in the body of the corresponding try statement. But this rule is only applicable to fully checked exceptions.

public class Test {
   public static void main(String[] args) {
      try {
         System.out.println("Hello");
      } catch(ArithmeticException e) { 
         // unchecked exception
      }
   }
}

Output:-

public class Test {
   public static void main(String[] args) {
      try {
         System.out.println("Hello");
      } catch(Exception e) { 
         // partially checked exception
      }
   }
}

Output:-

import java.io.*;
public class Test {
   public static void main(String[] args) {
      try {
         System.out.println("Hello");
      } catch(IOException e) { 
         // fully checked exception
      }
   }
}
public class Test {
   public static void main(String[] args) {
      try {
         System.out.println("Hello");
      } catch(InterruptedException e) { 
         // fully checked exception
      }
   }
}
public class Test {
   public static void main(String[] args) {
      try {
         System.out.println("Hello");
      } catch(Error e) { 
         // unchecked exception
      }
   }
}

Output:-

Summary on Exception Handling Keyword

  1. try:- To maintain risky code.
  2. catch:- To maintain exception handling code.
  3. finally:- To maintain cleanup code.
  4. throw:- To handover our created exception object to the JVM manually.
  5. throws:- To delegate the responsibility of exception handling to the caller.

Various Possible Compile time-errors in Exception Handling

  1. Unreported exception Xxx; must be caught or declared to be thrown:- When there is a statement that may raise a checked exception & we are not handling it.
  2. Exception Xxx has already been caught:- try with multiple catch blocks; the order of catch blocks is important.
  3. Exception Xxx is never thrown in the body of the corresponding try statement:- When we are handling a fully checked exception but there is no chance to raise it in the try block.
  4. Unreachable statement:- There is some code after the “throw …” statement.
  5. Incompatible types; found: Test; required: java.lang.Throwable
  6. try without catch or finally
  7. catch without try
  8. finally without try

Customized / User-defined Exception

  • throw keyword is best suitable for user-defined or customized exceptions but not for pre-defined exceptions.
  • It is highly recommended to define customized exception as unchecked i.e. we should extend the custom exception class from RuntimeException but not from the Exception class.

If you enjoyed this post, share it with your friends. Do you want to share more information about the topic discussed above or do you find anything incorrect? Let us know in the comments. Thank you!

Leave a Comment

Your email address will not be published. Required fields are marked *