Skip to main content

Throw & Throws

Java Exception Handling: Throw and Throws

Throw

Sometimes we can create exception objects explicitly and hand them over to the JVM manually. For this, we have to use the throw keyword. Thus, the main objective of the throw keyword is to hand over our created exception object to the JVM manually.

throw new ArithmeticException("division by zero");

Hence, the result of the following two programs is the same.

JVM creates exception object Programmer creates exception object
class Test {
    public static void main(String[] args) {
        System.out.print(10/0);
    }
}

Output:

Exception in thread "main" java.lang.ArithmeticException: / by zero
    at Test.main(Test.java:4)

In this case, the main method is responsible for creating the exception object and handing it over to the JVM.

class Test {
    public static void main(String[] args) {
        throw new ArithmeticException("/ by zero");
    }
}

Output:

Exception in thread "main" java.lang.ArithmeticException: / by zero
    at Test.main(Test.java:4)

In this case, the programmer creates the exception object explicitly and hands it over to the JVM manually.

Note:

The best use of the throw keyword is for user-defined or customized exceptions.

Case 1:

throw e; if e refers to null, then we will get a NullPointerException.

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

Output:

NullPointerException

Case 2:

We are not allowed to write any statement directly after throw; otherwise, we will get a compile-time error saying "unreachable statement."

Runtime Exception (allowed) Throw with unreachable statement (error)
class Test {
    public static void main(String[] args) {
        System.out.print(10/0);
        System.out.print("Hello");
    }
}

Runtime Exception

class Test {
    public static void main(String[] args) {
        throw new ArithmeticException("/ by zero");
        System.out.print("Hello");
    }
}

Compile Time Error: unreachable statement

Case 3:

We can use the throw keyword only for Throwable types. If we try to use it for normal Java objects, we will get a compile-time error.

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

Compile Time Error:

Test.java:4: error: incompatible types: Test cannot be converted to Throwable
    throw new Test();
    ^
1 error
class Test extends RuntimeException {
    public static void main(String[] args) {
        throw new Test();
    }
}

Output:

Exception in thread "main" Test
    at Test.main(Test.java:4)

Throws

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

Example 1:

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

Compile time error: unreported exception java.io.FileNotFoundException must be caught or declared to be thrown.

Example 2:

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

Compile time error: unreported exception java.lang.InterruptedException must be caught or declared to be thrown.

We can handle this compile-time error by using the following two ways:

  1. try-catch:
    class Test {
        public static void main(String[] args) {
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
            }
        }
    }
  2. throws: We can use the throws keyword to delegate responsibility of exception handling to the caller (it may be another method or JVM). Then the caller method is responsible to handle that exception.
    class Test {
        public static void main(String[] args) throws InterruptedException {
            Thread.sleep(1000);
        }
    }

Points:

  • The throws keyword is required only for checked exceptions. Usage of the throws keyword for unchecked exceptions has no use or impact.
  • The throws keyword is required only to convince the compiler. Usage of the throws keyword does not prevent abnormal termination of the program.
    class HelloWorld {
        public static void main(String args[]) throws InterruptedException {
            dco();
        }
        public static void dco() throws InterruptedException {
            doo();
        }
        public static void doo() throws InterruptedException {
            dooo();
        }
        public static void dooo() throws InterruptedException {
            Thread.sleep(1000);
        }
    }

    In the above program, at least one throws keyword is needed; otherwise, the code won't compile.

Conclusion of throws keyword:

  • We can use it to delegate responsibility of exception handling to the caller (it may be a method or JVM).
  • It is required only for checked exceptions and has no impact for unchecked exceptions.
  • It is required only to convince the compiler and does not prevent abnormal termination of the program.

Note:

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

Case 1:

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

class HelloWorld {
    HelloWorld() throws Exception {
    }
    public static void DO() throws Exception {
    }
    public static void main(String args[]) {
    }
}

Case 2:

We can use the throws keyword only for Throwable types. If we try to use it for normal Java classes, we will get a compile-time error saying "incompatible types."

Invalid (not Throwable) Valid (Throwable)
class Test {
    public static void main(String[] args) throws Test {
        System.out.println("Hello, World!");
    }
}

incompatible types: Test cannot be converted to Throwable

class Test extends RuntimeException {
    public static void main(String[] args) throws Test {
        System.out.println("Hello, World!");
    }
}

Case 3:

Checked Exception (requires handling) Error (no handling required)
class Test {
    public static void main(String[] args) {
        throw new Exception();
    }
}

CE: unreported exception Exception; must be caught or declared to be thrown

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

RE:

Exception in thread "main" java.lang.Error

Case 4:

Within the try block, if there is no chance of raising an exception, we can't write a catch block for that exception; otherwise, we will get a compile-time error saying "Exception XXX never thrown in body of corresponding try statement." But this rule is applicable for fully checked exceptions.

Unchecked Exception (allowed) Checked Exception (not allowed)
class HelloWorld {
    public static void main(String[] args) {
        try {
            System.out.print("Hello");
        } catch (ArithmeticException e) {
        }
    }
}
import java.io.*;
class HelloWorld {
    public static void main(String[] args) {
        try {
            System.out.print("Hello");
        } catch (IOException e) {
        }
    }
}

error: exception IOException is never thrown in body of corresponding try statement

class HelloWorld {
    public static void main(String[] args) {
        try {
            System.out.print("Hello");
        } catch (Exception e) {
        }
    }
}
class HelloWorld {
    public static void main(String[] args) {
        try {
            System.out.print("Hello");
        } catch (InterruptedException e) {
        }
    }
}

error: exception InterruptedException is never thrown in body of corresponding try statement

class HelloWorld {
    public static void main(String[] args) {
        try {
            System.out.print("Hello");
        } catch (Error e) {
        }
    }
}

Popular posts from this blog

Java

Codes With Java — Basics Codes With Java Java tutorials & fundamentals About Contact Privacy Basic Fundamentals Java source file structure Import Statement Static Import Packages Data Type Variables Final Variable Declaration and Access Modifier Inner classes applicable modifiers Static Modifier Synchronized Native Transient Volatile Interface Introduction Interface Declaration and Implementation Interface methods and variables Naming Conflicts Interface Marker interface and Ad...

Short Circuite Operators part 4

                                                             Short Circuit Operators In  Java logical operators , if the evaluation of a logical expression exits in between before complete evaluation, then it is known as  Short-circuit . A short circuit happens because the result is clear even before the complete evaluation of the expression, and the result is returned. Short circuit evaluation avoids unnecessary work and leads to efficient processing. 1-: AND(&&) 2-:OR(||) these are exactly same as bitwise operators (&,|) except the following differences. Single Short Circuit Operator(&,|) Both arguments Should be evaluated always. relatively performance is low. Applicable for both boolean and Integral types. Double Short Circuit Operator(...

Final Variable

Final Instance Variable If the value of a variable changes from object to object, such a variable is called an instance variable . For every object, a separate copy of the instance variable will be created. Instance variables do not require explicit initialization; JVM always provides default values. Example: class Test { int x; // instance variable public static void main(String... args) { Test t = new Test(); System.out.println(t.x); // output: 0 } } If the instance variable is declared as final , then explicit initialization is mandatory. JVM will NOT provide default values. Example: class Test { final int x; } Compile-time Error: variable x might not have been initialized. Rule: A final instance variable must be initialized before constructor completion . Possible places for initialization: 1. At the time of declaration class Test { final int x = 10; } 2. Inside an instance blo...