DEV Community

Cover image for Difference between throw and throws
Gosu Code
Gosu Code

Posted on

Difference between throw and throws

Among throw and throws, the throws keyword is considered riskier, while throw is more straightforward.

throw keyword

The below picture shows how exception object is thrown by programmer to JVM

throw keyword in java

throw keywordSometimes we can create Exception object explicitly and we can handover to the JVM manually for this we have to use throw keyword.

throw new ArithmeticException("/ by zero");
Enter fullscreen mode Exit fullscreen mode

throw : Manually passes the created exception object to the JVM.

new ArithmeticException("/ by zero"); : Creates exception object explicitly.

Example:-
In both cases below, the output remains the same:
throw keyword

In the first example, main method is responsible for creating exception object whereas in second example, programmer is responsible for creating an exception object.

These both program have the same output:

Exception in thread "main" java.lang.ArithmeticException: / by zero
        at ThrowNThrows.Test.main(Test.java:5)
Enter fullscreen mode Exit fullscreen mode

But,

Why explicitly create exceptions?

Consider a banking system where a user attempts to withdraw more money than is available. The system returns an error like "Insufficient funds in your account." You don't have an exception like InsufficientFundException in JAVA predefined, so you have to create your own. Internally, this is handled using a custom exception:

withdraw(double amount){
  if(amount > balance){
      throw new InsufficientFundException();
  }
}
Enter fullscreen mode Exit fullscreen mode

Just like in the above example, the best use of throw keyword is for user defined exceptions or customized exceptions. We'll discuss about customized exception later in the blog.

throw keyword is mostly used for customized exception.

Edge Cases for throw

CASE 1: Throwing an Exception Object

We can manually create an exception object and throw it. This works fine.

class Test1 {
  static ArithmeticException e = new ArithmeticException(); // creating exception object
  public static void main(String[] args) {
    throw e;
  }
}
Enter fullscreen mode Exit fullscreen mode

Output:-

Exception in thread "main" java.lang.ArithmeticException
        at ThrowNThrows.Test1.<clinit>(Test1.java:5)
        at java.base/java.lang.Class.forName0(Native Method)
Enter fullscreen mode Exit fullscreen mode

Problem: Throwing an Uninitialized Exception

If the exception object is not initialized, throw will result in a NullPointerException.

class Test2 {
  static ArithmeticException e;  // default object value null
  public static void main(String[] args) {
    throw e;  // e refers null
  }
}
Enter fullscreen mode Exit fullscreen mode

Output:-

Exception in thread "main" java.lang.NullPointerException: Cannot throw exception because "ThrowNThrows.Test2.e" is null
        at ThrowNThrows.Test2.main(Test2.java:8)
Enter fullscreen mode Exit fullscreen mode

CASE 2: Unreachable Code After throw

If an exception occurs at runtime, the next statement will not execute.

class Test {
  public static void main(String[] args) {
    System.out.println(10 / 0);
    System.out.println("Hello");  // will not be executed
  }
}
Enter fullscreen mode Exit fullscreen mode

Output:-

Exception in thread "main" java.lang.ArithmeticException: / by zero
        at ThrowNThrows.CASE2.Test.main(Test.java:5)
Enter fullscreen mode Exit fullscreen mode

Problem: Compiler Error for Unreachable Code

When using throw, the compiler detects unreachable code, leading to a compile-time error.

class Test {
  public static void main(String[] args) {
    throw new ArithmeticException("/ by zero");
    System.out.println("Hello");  // Unreachable code
  }
}
Enter fullscreen mode Exit fullscreen mode

Note: After a throw statement, no further code can be executed unless handled with conditions like if-else.

CASE 3: Throwing Non-Throwable Objects

Only objects of Throwable type can be thrown. If we attempt to throw a normal Java object, it results in a compilation error.

class Test {
  public static void main(String[] args) {
    throw new Test(); // Incompatible types
  }
}
Enter fullscreen mode Exit fullscreen mode

Output:-

ThrowNThrows/CASE3/Test.java:5: error: incompatible types: Test cannot be converted to Throwable
   throw new Test();
    ^
1 error
Enter fullscreen mode Exit fullscreen mode

error: compilation failed
Solution: Extending Throwable

If the class extends RuntimeException, it can be thrown.

class Test2 extends RuntimeException {
  public static void main(String[] args) {
    throw new Test2();
  }
}
Enter fullscreen mode Exit fullscreen mode

Output:-

Exception in thread "main" ThrowNThrows.CASE3.Test2
        at ThrowNThrows.CASE3.Test2.main(Test2.java:5)
Enter fullscreen mode Exit fullscreen mode

throws keyword

The throws keyword is used when a method might throw a checked exception.
Example 1: Checked exception (FileNotFoundException)

import java.io.PrintWriter;

class WritingInFile {
  public static void main(String[] args) {
    PrintWriter pw = new PrintWriter("abc.txt");
    pw.println("Hello");
  }
}
Enter fullscreen mode Exit fullscreen mode

Trying to access a file that may not be available will give an exception.

Output:

❯ javac WritingInFile.java
WritingInFile.java:5: error: unreported exception FileNotFoundException; must be caught or declared to be thrown 
    PrintWriter pw = new PrintWriter("abc.txt");
                     ^
1 error
Enter fullscreen mode Exit fullscreen mode

Example 2:

class Sleep {
  public static void main(String[] args) {
    Thread.sleep(10000);  //sleeps for 10 seconds
  }
}
Enter fullscreen mode Exit fullscreen mode

Whenever we call sleep method there may be a chance that main method may sleep, so it'll give an exception.
Output:

ThrowNThrows/Throws/Sleep.java:5: error: unreported exception InterruptedException; must be caught or declared to be thrown
    Thread.sleep(10000);
                ^
1 error
error: compilation failed
Enter fullscreen mode Exit fullscreen mode

Ways to Handle Checked Exceptions

Way 1: Using try-catch(Recommended)

When you want to handle the exception on your own, you use try-catch .

class SleepProgram {
  public static void main(String[] args) {
    try{
      Thread.sleep(10000);  //sleeps for 10 seconds
    } catch(InterruptedException e){
      System.out.println("Exception handled");
    }
  }
}
Enter fullscreen mode Exit fullscreen mode

Way 2: Using throws (Delegates responsibility to caller)

When you need to pass/delegate the responsibility of handling exception to the caller method, we can use throws keyword.

class SleepProgram{
  public static void main(String[] args) throws InterruptedException{
      Thread.sleep(10000);
  }
}
Enter fullscreen mode Exit fullscreen mode

Here, the JVM handles the exception.
Key points:

  • throws keyword is only required for checked exception.
  • There is no impact of throws keyword in unchecked exception
  • throws keyword is required only to convince compiler
  • Uses of throws keyword doesn't prevent abnormal termination of the program.

Example: Exception Delegation
In this example, exceptions are delegated from methods to methods and finally to the JVM so we don't get any compile time error.

class Test {
  public static void main(String[] args) throws InterruptedException {
    doStuff();
  }

  public static void doStuff() throws InterruptedException {
    doMoreStuff();
  }

  public static void doMoreStuff() throws InterruptedException {
    Thread.sleep(5000);
  }
}
Enter fullscreen mode Exit fullscreen mode

Try removing throws InterruptedException from different methods to observe compile-time errors.

Edge Cases for throws

CASE 1: Allowed for Methods & Constructors, Not for Classes

We can use throws keyword for methods and constructor but not for classes.

class Test{

  Test() throws Exception {
  }

  public void m1() throws Exception {
  }
}
Enter fullscreen mode Exit fullscreen mode

CASE 2: throws Must Be Used with Throwable Types

class Test{
  public void m1() throws Test{   // ❌ Compile-time error
  }
}
Enter fullscreen mode Exit fullscreen mode

Solution:

class Test extends RuntimeException{
  public void m1() throws Test{  // ✅ Valid
  }
}
Enter fullscreen mode Exit fullscreen mode

The above code is valid because class Test is of type throwable . We can use throws keyword only for throwable types. If we try to use it for normal JAVA classes, then we will get compile time error saying incompatible types.

CASE 3: Checked vs. Unchecked Exceptions

Can you tell which will program will compile?

which code will compile?

The answer is, First one… will not compile. Because Exception is a checked exception, so if we don't handle it compulsorily the program will not compile. Whereas, Error is unchecked exception so the second one will compile fine but we will get runtime exception.

CASE 4:

Take a look at these codes and try to answer which of these are gonna run. Hint: out of these five, three codes runs perfectly.

CASE 4

Did you guess the answer? The answer is 2, 4 and 5. 1 and 3 will not be able to run.

Inside a try block if there is no chance of rising an exception then we can't write catch block for that exception otherwise we will get compile time error saying, Exception xxx is never thrown in body of corresponding try statement. But this rule is applicable only for fully checked exception.

Top comments (0)