Java Notes
Complete guide to throw and throws keywords in Java — how to manually throw exceptions, declare checked exceptions, method signatures, exception propagation, and real-world patterns.
Overview
Java provides two keywords for working with exceptions proactively:
| Keyword | Purpose | Location | Used With |
|---|---|---|---|
throw | Actually throws an exception object | Inside method body | Exception instance |
throws | Declares that a method might throw exceptions | Method signature | Exception class names |
Think of it this way:
throw= "I'm throwing this ball NOW" (action)throws= "Warning: I might throw a ball" (declaration)
The throw Keyword
Syntax
throw new ExceptionType("error message");Basic Example
public class ThrowExample {
public static void main(String[] args) {
try {
validateAge(15);
} catch (IllegalArgumentException e) {
System.out.println("Validation failed: " + e.getMessage());
}
try {
validateAge(25);
System.out.println("Age 25 is valid!");
} catch (IllegalArgumentException e) {
System.out.println("Validation failed: " + e.getMessage());
}
}
static void validateAge(int age) {
if (age < 18) {
throw new IllegalArgumentException(
"Age must be 18 or above. Got: " + age);
}
System.out.println("Validation passed for age: " + age);
}
}Output:
How throw Works Internally
| 1. Exception object created | |
|---|---|
| 2. Stack trace captured | |
| 3. Method exits immediately | |
| 4. Caller's catch is checked |
Throwing Different Exception Types
public class ThrowVariousExceptions {
// Throwing unchecked exceptions (no declaration needed)
static void divide(int a, int b) {
if (b == 0) {
throw new ArithmeticException("Cannot divide by zero");
}
System.out.println(a + " / " + b + " = " + (a / b));
}
static void processName(String name) {
if (name == null) {
throw new NullPointerException("Name cannot be null");
}
if (name.trim().isEmpty()) {
throw new IllegalArgumentException("Name cannot be empty");
}
if (name.length() > 50) {
throw new IllegalArgumentException(
"Name too long: max 50 characters, got " + name.length());
}
System.out.println("Processing: " + name);
}
public static void main(String[] args) {
// Test divide
try {
divide(10, 2);
divide(10, 0);
} catch (ArithmeticException e) {
System.out.println("Error: " + e.getMessage());
}
System.out.println();
// Test processName
String[] names = {"Alice", null, "", "Bob"};
for (String name : names) {
try {
processName(name);
} catch (NullPointerException e) {
System.out.println("Null error: " + e.getMessage());
} catch (IllegalArgumentException e) {
System.out.println("Invalid: " + e.getMessage());
}
}
}
}Output:
| Error | Cannot divide by zero |
| Processing | Alice |
| Null error | Name cannot be null |
| Invalid | Name cannot be empty |
| Processing | Bob |
Re-throwing an Exception
Sometimes you want to catch an exception, do something (like logging), and then re-throw it:
public class RethrowExample {
public static void main(String[] args) {
try {
processOrder(null);
} catch (Exception e) {
System.out.println("Main caught: " + e.getMessage());
}
}
static void processOrder(String orderId) {
try {
if (orderId == null) {
throw new IllegalArgumentException("Order ID is null");
}
// process order...
} catch (IllegalArgumentException e) {
System.out.println("LOG: Order processing failed - " + e.getMessage());
// Re-throw after logging
throw e; // Same exception object, preserves stack trace
}
}
}Output:
Wrapping Exceptions (Exception Chaining)
public class ExceptionChaining {
public static void main(String[] args) {
try {
loadUserProfile("user123");
} catch (RuntimeException e) {
System.out.println("Error: " + e.getMessage());
System.out.println("Caused by: " + e.getCause().getMessage());
}
}
static void loadUserProfile(String userId) {
try {
// Simulating database error
throw new java.sql.SQLException("Connection refused on port 5432");
} catch (java.sql.SQLException e) {
// Wrap low-level exception in a higher-level one
throw new RuntimeException(
"Failed to load profile for user: " + userId, e);
}
}
}Output:
The throws Keyword
Syntax
returnType methodName(parameters) throws ExceptionType1, ExceptionType2 {
// method body
}Why throws is Needed
The throws keyword is required when a method can throw a checked exception that it doesn't handle internally. It tells the compiler (and the caller) that this method might throw this exception.
Output:
Multiple Exceptions in throws
import java.io.IOException;
import java.sql.SQLException;
public class MultipleThrows {
// Declaring multiple checked exceptions
static void transferData(String source, String destination)
throws IOException, SQLException {
if (source == null) {
throw new IOException("Source file is null");
}
if (destination == null) {
throw new SQLException("Database destination is null");
}
System.out.println("Transferring data from " + source +
" to " + destination);
}
public static void main(String[] args) {
try {
transferData("users.csv", "users_table");
transferData(null, "users_table");
} catch (IOException e) {
System.out.println("File error: " + e.getMessage());
} catch (SQLException e) {
System.out.println("DB error: " + e.getMessage());
}
}
}Output:
Exception Propagation with throws
When a method declares throws, the exception propagates UP the call stack:
import java.io.IOException;
public class PropagationDemo {
// Level 3: throws exception
static void level3() throws IOException {
System.out.println(" Level 3: Throwing IOException");
throw new IOException("Disk full");
}
// Level 2: propagates (doesn't handle)
static void level2() throws IOException {
System.out.println(" Level 2: Calling level3()");
level3();
System.out.println(" Level 2: After level3() (won't print)");
}
// Level 1: propagates (doesn't handle)
static void level1() throws IOException {
System.out.println("Level 1: Calling level2()");
level2();
System.out.println("Level 1: After level2() (won't print)");
}
// Main: handles the exception
public static void main(String[] args) {
System.out.println("Main: Calling level1()");
try {
level1();
} catch (IOException e) {
System.out.println("\nMain: Caught exception!");
System.out.println("Main: " + e.getMessage());
}
System.out.println("Main: Program continues");
}
}Output:
| Main | Calling level1() |
| Level 1 | Calling level2() |
| Level 2 | Calling level3() |
| Level 3 | Throwing IOException |
| Main | Caught exception! |
| Main | Disk full |
| Main | Program continues |
Propagation Diagram:
throw vs throws — Complete Comparison
import java.io.IOException;
public class ThrowVsThrows {
// 'throws' in method signature (declaration)
// 'throw' in method body (action)
static void processFile(String filename) throws IOException {
if (filename == null) {
throw new IllegalArgumentException("Filename is null"); // throw (unchecked)
}
if (filename.isEmpty()) {
throw new IOException("Filename is empty"); // throw (checked - matches throws)
}
System.out.println("Processing: " + filename);
}
public static void main(String[] args) {
String[] files = {"report.txt", null, "", "data.csv"};
for (String file : files) {
try {
processFile(file);
} catch (IllegalArgumentException e) {
System.out.println(" Invalid arg: " + e.getMessage());
} catch (IOException e) {
System.out.println(" IO problem: " + e.getMessage());
}
}
}
}Output:
| Processing | report.txt |
| Invalid arg | Filename is null |
| IO problem | Filename is empty |
| Processing | data.csv |
#
Q8: Can you throw checked exceptions without declaring them?
A: No. If a method throws a checked exception, it MUST either (1) catch it within the method, or (2) declare it in the method signature with throws. Unchecked exceptions (RuntimeException subclasses) do NOT require declaration. Violating this rule causes a compile error.
Q9: What is exception wrapping (chaining)?
A: Catching a low-level exception and throwing a new higher-level exception with the original as the cause: catch (SQLException e) { throw new DataAccessException("Query failed", e); }. This preserves the root cause (accessible via getCause()) while providing context-appropriate abstraction.
Q10: Can a constructor throw exceptions?
A: Yes! Constructors can throw both checked and unchecked exceptions. If a constructor throws, the object is NOT created (new returns nothing, partial construction is garbage collected). Checked exceptions in constructors must be declared with throws just like methods.
Q11: What is the difference between "throw" and "throws" in method overriding?
A: Overriding methods can throw: (1) same exceptions as parent, (2) subclass exceptions (narrower), (3) fewer exceptions, or (4) no exceptions. They CANNOT throw broader checked exceptions or new checked exceptions not declared by the parent. Unchecked exceptions have no restrictions in overriding.
Q12: What happens if you throw an exception inside a catch block?
A: The exception propagates normally to the next enclosing try-catch or up the call stack. The finally block (if any) still executes before the exception leaves the method. This is commonly done for exception chaining or re-throwing after logging.
Summary Table
| Feature | throw | throws |
|---|---|---|
| What it does | Throws an exception object | Declares possible exceptions |
| Where used | Inside method body | In method signature |
| Followed by | Exception instance (new Exception()) | Exception class names |
| Count | One exception at a time | Multiple (comma-separated) |
| Required for | Both checked and unchecked | Only checked exceptions |
| Example | throw new IOException("msg") | void m() throws IOException |
When to Use throw vs throws
Use throw when:
- Input validation fails
- Business rules are violated
- You need to convert one exception type to another
- You want to re-throw a caught exception
Use throws when:
- Your method calls another method that throws a checked exception
- Your method intentionally throws a checked exception
- You want the caller to decide how to handle the error
Real-World Example: User Registration System
Output:
| ✓ User registered | Alice Johnson (alice@example.com) |
| ✗ Registration failed | Name cannot be empty |
| ✗ Registration failed | Invalid email format: invalid-email |
| ✗ Registration failed | Email already registered: admin@company.com |
| ✗ Registration failed | Must be at least 13 years old. Got: 10 |
| ✓ User registered | Frank Wilson (frank@test.com) |
Throws with Method Overriding Rules
When overriding methods, there are strict rules about throws:
import java.io.IOException;
import java.io.FileNotFoundException;
class Parent {
void display() throws IOException {
System.out.println("Parent display");
}
void process() throws IOException {
System.out.println("Parent process");
}
void calculate() {
System.out.println("Parent calculate");
}
}
class Child extends Parent {
// ✅ RULE 1: Can throw same exception
@Override
void display() throws IOException {
System.out.println("Child display");
}
// ✅ RULE 2: Can throw subclass exception (narrower)
// FileNotFoundException is subclass of IOException
@Override
void process() throws FileNotFoundException {
System.out.println("Child process");
}
// ✅ RULE 3: Can choose NOT to throw
// @Override
// void display() { } // Fine! No throws needed
// ❌ RULE 4: CANNOT throw broader/new checked exception
// @Override
// void calculate() throws IOException { } // COMPILE ERROR!
// Parent didn't declare throws, child cannot add checked exception
}
public class OverridingThrows {
public static void main(String[] args) {
Parent obj = new Child();
try {
obj.display();
obj.process();
} catch (IOException e) {
System.out.println("Error: " + e.getMessage());
}
}
}Parent display Child display Parent process Child process throws IOException
Rules Summary:
- Child can throw the same exception as parent
- Child can throw a subclass (narrower) exception
- Child can choose not to throw any exception
- Child CANNOT throw a broader or new checked exception
Common Mistakes
1. Using throw with a class instead of an object
// ❌ WRONG: throw expects an object, not a class
throw IOException;
// ✅ CORRECT: Create an instance
throw new IOException("Error message");2. Code after throw statement
// ❌ WRONG: Unreachable code
void method() {
throw new RuntimeException("error");
System.out.println("hello"); // Compile error: unreachable
}3. Declaring unchecked exceptions in throws (unnecessary)
// Not wrong, but unnecessary and misleading
void method() throws NullPointerException, ArithmeticException {
// Unchecked exceptions don't need throws declaration
}
// ✅ Better: Just document them in Javadoc
/**
* @throws NullPointerException if input is null
*/
void method() {
// ...
}4. Declaring throws Exception everywhere
// ❌ BAD: Too broad, forces callers to catch Exception
void doStuff() throws Exception { }
// ✅ GOOD: Be specific
void doStuff() throws IOException, SQLException { }Interview Questions
Q1: What is the difference between throw and throws?
Answer: throw is used inside a method body to actually throw an exception object. throws is used in the method declaration to indicate which checked exceptions the method might throw. throw is followed by an exception instance; throws is followed by exception class names.
Q2: Can we throw unchecked exceptions without declaring throws?
Answer: Yes. Unchecked exceptions (subclasses of RuntimeException) do not require a throws declaration. You can throw new RuntimeException() from any method without declaring it.
Q3: Can a method throw an exception that is NOT declared in its throws clause?
Answer: Only unchecked exceptions. If a method throws a checked exception, it MUST be declared in the throws clause. If not, you get a compilation error.
Q4: What happens if main() uses throws?
Answer: The exception propagates to the JVM, which handles it via the default exception handler (prints stack trace and terminates). Example: public static void main(String[] args) throws IOException { ... }
Q5: Can we re-throw a caught exception?
Answer: Yes. Inside a catch block, you can use throw e; to re-throw the same exception, or throw new AnotherException("msg", e); to wrap it in a different exception (exception chaining).
Q6: How does throws work with method overriding?
Answer: The overriding method can throw the same exception, a subclass exception, or no exception at all. It CANNOT throw a broader checked exception or a new checked exception not declared by the parent method.
Exam Focus
Revise definitions, diagrams, examples, and short-answer points for throw and throws Keywords in Java.
Interview Use
Prepare one clear explanation, one practical example, and one common mistake for this Java Master Course topic.
Search Terms
java-master-course, java master course, java, master, course, exception, handling, throw
Related Java Master Course Topics