When working with Java, handling exceptions properly is crucial to writing robust and maintainable applications. Two essential keywords in Java’s exception-handling mechanism are throw
and throws
. While they may look similar, they serve different purposes. In this guide, we will explore how to use throw
and throws
effectively in Java, ensuring clarity and proper exception handling.
Understanding throw and throws in Java
Both throw
and throws
relate to Java’s exception-handling framework, but they are used differently:
throw
: Used within a method to explicitly throw an exception.throws
: Declares exceptions that a method might throw.
Now, let’s explore both in detail with examples.
Understanding throw
in Java
The throw
keyword in Java is used to manually create and throw an exception object. This allows the programmer to explicitly indicate exceptional conditions in the program flow.
throw new ArithmeticException("/ by zero");
In this example, an ArithmeticException
object is created explicitly with the message “/ by zero” and thrown using the throw
keyword.
The main objective of the throw
keyword is to hand over the created exception object to the JVM manually.
The following two programs yield exactly the same result:
Without throw
keyword:
class Test {
public static void main(String[] args) {
System.out.println(10/0);
}
}
//output
Exception in thread "main" java.lang.ArithmeticException: / by zero
at Test.main(Test.java:3)
In this case, the main
method is responsible for causing the ArithmeticException
and implicitly hands over the exception object to the JVM.
With throw
keyword:
class Test {
public static void main(String[] args) {
throw new ArithmeticException("/ by zero");
}
}
//o/p
Exception in thread "main" java.lang.ArithmeticException: / by zero
at Test.main(Test.java:3)
In this case, the main
method explicitly creates an ArithmeticException
object using throw
keyword and hands it over to the JVM.
Here is one more example.
public class ThrowExample {
static void checkAge(int age) {
if (age < 18) {
throw new IllegalArgumentException("Age must be 18 or above");
} else {
System.out.println("Access granted.");
}
}
public static void main(String[] args) {
checkAge(15); // This will throw an exception
}
}
Here,
- The method
checkAge(int age)
checks whether the given age is 18 or more. - If the condition is not met,
throw
is used to raise anIllegalArgumentException
. - This terminates program execution unless the exception is caught and handled. The
throw
statement stops execution of the current block and transfers control to the nearest exception handler.
Understanding throws
in Java
In Java, if there is a possibility of a checked exception being thrown within a method, the method must either handle the exception using a try-catch block or declare that it throws the exception using the throws
keyword in its method signature.
import java.io.*;
class Test {
public static void main(String[] args) {
PrintWriter pw = new PrintWriter("abc.txt");
pw.println("Hello");
}
}
//Compilation Error: unreported exception java.io.FileNotFoundException; must be caught or declared to be thrown
In this example, the PrintWriter
constructor can throw a FileNotFoundException
, a checked exception. Since it’s not handled within the main
method, it results in a compilation error.
To handle this error, you can either use a try-catch block to handle the exception:
import java.io.*;
class Test {
public static void main(String[] args) {
try {
PrintWriter pw = new PrintWriter("abc.txt");
pw.println("Hello");
} catch (FileNotFoundException e) {
// Handle the exception
e.printStackTrace();
}
}
}
Or you can declare that the method throws the exception using the throws
keyword:
import java.io.*;
class Test {
public static void main(String[] args) throws FileNotFoundException {
PrintWriter pw = new PrintWriter("abc.txt");
pw.println("Hello");
}
}
Using the throws
keyword delegates the responsibility of handling the exception to the caller of the method.
Here is another example.
import java.io.IOException;
public class ThrowsExample {
static void readFile() throws IOException {
throw new IOException("File not found");
}
public static void main(String[] args) {
try {
readFile();
} catch (IOException e) {
System.out.println("Exception handled: " + e.getMessage());
}
}
}
Here,
- The
readFile
method declaresthrows IOException
, meaning it might throw anIOException
. - Instead of handling the exception inside
readFile
, it delegates handling to the caller (main
method). - The
main
method catches the exception using atry-catch
block, preventing the program from crashing.
Note: It’s recommended to handle exceptions using try-catch blocks where possible, as using throws
may propagate exceptions up the call stack without handling them properly.
Key Differences Between throw
and throws
Feature | throw | throws |
---|---|---|
Purpose | Used to explicitly throw an exception | Declares exceptions a method can throw |
Location | Inside the method body | In the method signature |
Number of Exceptions | Can only throw one exception at a time | Can declare multiple exceptions separated by commas |
Propagation | Stops execution immediately unless handled | Informs the caller to handle the exception |
Best Practices for Using throw
and throws
1. Use throw
for Specific Error Conditions
When you detect a problem in your logic, use throw
to raise an appropriate exception. Always provide meaningful error messages to help debugging.
2. Use throws
for Method-Level Exception Handling
If a method performs an operation that may result in an exception (e.g., file handling, database access), use throws
to declare it and let the caller handle it.
3. Catch and Handle Exceptions Properly
Declaring exceptions using throws
does not replace exception handling. Always use try-catch
blocks where necessary.
4. Avoid Overusing throws
Overusing throws
can make a method difficult to use, as the caller must handle multiple exceptions. Only declare exceptions when handling them inside the method is impractical or when the caller needs to decide how to respond.
Conclusion
Understanding how to use throw
and throws
effectively in Java is key to writing robust applications. throw
is used to generate exceptions manually, while throws
is used to declare potential exceptions in a method. By following best practices, you can ensure better error handling and maintainable code.