Home/Java/Throw & Throws in Java

Throw & Throws in Java

Learn how to signal and declare exceptions in your code

💡 Think of 'throw' like throwing a ball to someone - you actively toss it! And 'throws' is like warning 'Hey, I might throw a ball to you!' before you do it. One is the action, the other is the warning!

🎾 The throw Keyword

The 'throw' keyword is used to explicitly throw an exception. You create and throw an exception object when something goes wrong in your code.

ThrowExample.java
java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
public class ThrowExample {
public static void main(String[] args) {
// Example 1: Throwing an exception manually
try {
checkAge(15);
} catch (IllegalArgumentException e) {
System.out.println("Caught: " + e.getMessage());
}
try {
checkAge(25);
} catch (IllegalArgumentException e) {
System.out.println("Caught: " + e.getMessage());
}
}
public static void checkAge(int age) {
System.out.println("\nChecking age: " + age);
if (age < 18) {
// Throwing an exception manually!
throw new IllegalArgumentException(
"Age must be 18 or older. Got: " + age
);
}
System.out.println("Age is valid!");
}
}
// Output:
// Checking age: 15
// Caught: Age must be 18 or older. Got: 15
//
// Checking age: 25
// Age is valid!

⚠️ The throws Keyword

The 'throws' keyword is used in method signatures to declare that a method might throw certain exceptions. It's a warning to anyone calling the method.

ThrowsExample.java
java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
import java.io.IOException;
public class ThrowsExample {
public static void main(String[] args) {
try {
// We MUST handle the exception because readFile declares it
readFile("data.txt");
} catch (IOException e) {
System.out.println("Error: " + e.getMessage());
}
}
// The 'throws' keyword declares that this method might throw IOException
public static void readFile(String filename) throws IOException {
System.out.println("Reading file: " + filename);
// Simulating a file read error
if (filename.equals("data.txt")) {
// We throw the exception here
throw new IOException("File not found: " + filename);
}
System.out.println("File read successfully!");
}
}
// Output:
// Reading file: data.txt
// Error: File not found: data.txt
// Note: The 'throws IOException' in the method signature warns callers
// that they need to handle this exception!

🔍 🔄 Key Differences

Understanding when to use throw vs throws:

1

throw

Used inside method body to actually throw an exception

2

throws

Used in method signature to declare possible exceptions

3

throw usage

throw new Exception('message')

4

throws usage

public void method() throws Exception

ThrowVsThrows.java
java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
import java.io.IOException;
public class ThrowVsThrows {
public static void main(String[] args) {
try {
demonstrateThrowVsThrows();
} catch (IOException e) {
System.out.println("Main caught: " + e.getMessage());
}
}
// 'throws' - declares exception in method signature
public static void demonstrateThrowVsThrows() throws IOException {
System.out.println("Inside method...");
// 'throw' - actually throws the exception
throw new IOException("Something went wrong!");
// This line never executes
// System.out.println("This won't print");
}
}
// Key difference:
// - throws: Used in method declaration (warning)
// - throw: Used inside method body (action)
// Output:
// Inside method...
// Main caught: Something went wrong!

🎂 Real-World Example: Age Validation

AgeValidator.java
java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
public class AgeValidator {
public static void main(String[] args) {
// Test different ages
testRegistration("Alice", 25);
testRegistration("Bob", 15);
testRegistration("Charlie", -5);
testRegistration("Diana", 200);
}
public static void testRegistration(String name, int age) {
System.out.println("\n--- Registering: " + name + " ---");
try {
validateAge(age);
System.out.println("✓ Registration successful!");
} catch (IllegalArgumentException e) {
System.out.println("✗ Registration failed: " + e.getMessage());
}
}
public static void validateAge(int age) {
// Check for negative age
if (age < 0) {
throw new IllegalArgumentException(
"Age cannot be negative! Got: " + age
);
}
// Check for too young
if (age < 18) {
throw new IllegalArgumentException(
"Must be 18 or older. You are: " + age
);
}
// Check for unrealistic age
if (age > 150) {
throw new IllegalArgumentException(
"Age seems unrealistic: " + age
);
}
System.out.println("Age " + age + " is valid");
}
}
// Output:
// --- Registering: Alice ---
// Age 25 is valid
// ✓ Registration successful!
//
// --- Registering: Bob ---
// ✗ Registration failed: Must be 18 or older. You are: 15
//
// --- Registering: Charlie ---
// ✗ Registration failed: Age cannot be negative! Got: -5
//
// --- Registering: Diana ---
// ✗ Registration failed: Age seems unrealistic: 200

💰 Real-World Example: Bank Withdrawal

BankAccount.java
java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
public class BankAccount {
private String accountNumber;
private double balance;
public BankAccount(String accountNumber, double initialBalance) {
this.accountNumber = accountNumber;
this.balance = initialBalance;
}
// Method that throws exceptions for invalid operations
public void withdraw(double amount) {
System.out.println("\nAttempting to withdraw: $" + amount);
// Validation: Check for negative amount
if (amount < 0) {
throw new IllegalArgumentException(
"Withdrawal amount cannot be negative!"
);
}
// Validation: Check for zero amount
if (amount == 0) {
throw new IllegalArgumentException(
"Withdrawal amount must be greater than zero!"
);
}
// Validation: Check for insufficient funds
if (amount > balance) {
throw new IllegalArgumentException(
"Insufficient funds! Balance: $" + balance +
", Requested: $" + amount
);
}
// All validations passed - perform withdrawal
balance -= amount;
System.out.println("✓ Withdrawal successful!");
System.out.println("New balance: $" + balance);
}
public static void main(String[] args) {
BankAccount account = new BankAccount("ACC123", 1000.0);
System.out.println("Initial balance: $1000");
// Test valid withdrawal
try {
account.withdraw(200);
} catch (IllegalArgumentException e) {
System.out.println("Error: " + e.getMessage());
}
// Test overdraft
try {
account.withdraw(2000);
} catch (IllegalArgumentException e) {
System.out.println("Error: " + e.getMessage());
}
// Test negative amount
try {
account.withdraw(-50);
} catch (IllegalArgumentException e) {
System.out.println("Error: " + e.getMessage());
}
}
}
// Output:
// Initial balance: $1000
//
// Attempting to withdraw: $200.0
// ✓ Withdrawal successful!
// New balance: $800.0
//
// Attempting to withdraw: $2000.0
// Error: Insufficient funds! Balance: $800.0, Requested: $2000.0
//
// Attempting to withdraw: $-50.0
// Error: Withdrawal amount cannot be negative!

📝 Declaring Multiple Exceptions

MultipleThrows.java
java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
import java.io.IOException;
import java.sql.SQLException;
public class MultipleThrows {
public static void main(String[] args) {
try {
processData("users.txt", "database_url");
} catch (IOException e) {
System.out.println("File error: " + e.getMessage());
} catch (SQLException e) {
System.out.println("Database error: " + e.getMessage());
}
}
// Method that can throw MULTIPLE exceptions
// Separate them with commas!
public static void processData(String filename, String dbUrl)
throws IOException, SQLException {
System.out.println("Processing data...");
// Simulate file reading
if (filename.isEmpty()) {
throw new IOException("Filename cannot be empty!");
}
// Simulate database operation
if (dbUrl.isEmpty()) {
throw new SQLException("Database URL cannot be empty!");
}
System.out.println("Data processed successfully!");
}
}
// Key points:
// 1. Use 'throws' keyword followed by exception types
// 2. Separate multiple exceptions with commas
// 3. Caller must handle ALL declared exceptions
// 4. Order doesn't matter for 'throws' (unlike catch blocks)

🔄 Rethrowing Exceptions

RethrowingExceptions.java
java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
public class RethrowingExceptions {
public static void main(String[] args) {
try {
processUserInput("invalid");
} catch (IllegalArgumentException e) {
System.out.println("Main caught: " + e.getMessage());
}
}
// This method catches, logs, and rethrows
public static void processUserInput(String input)
throws IllegalArgumentException {
try {
validateInput(input);
} catch (IllegalArgumentException e) {
// Log the error
System.out.println("Logging error: " + e.getMessage());
// Do some cleanup
System.out.println("Performing cleanup...");
// Rethrow the exception for caller to handle
throw e; // Rethrowing the same exception
}
}
public static void validateInput(String input) {
if (input.equals("invalid")) {
throw new IllegalArgumentException("Input validation failed!");
}
}
}
// Output:
// Logging error: Input validation failed!
// Performing cleanup...
// Main caught: Input validation failed!
// Why rethrow?
// - Log or record the error
// - Perform cleanup operations
// - Let higher-level code decide how to handle it
// - Add context or wrap in different exception type

✅ Real-World Example: Form Validation

FormValidator.java
java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
public class FormValidator {
public static void main(String[] args) {
// Test valid form
testForm("alice@email.com", "SecurePass123", 25);
// Test invalid email
testForm("invalid-email", "password123", 25);
// Test weak password
testForm("bob@email.com", "123", 25);
// Test invalid age
testForm("charlie@email.com", "SecurePass123", 10);
}
public static void testForm(String email, String password, int age) {
System.out.println("\n=== Testing Form ===");
System.out.println("Email: " + email);
System.out.println("Password: " + password);
System.out.println("Age: " + age);
try {
validateEmail(email);
validatePassword(password);
validateAge(age);
System.out.println("✓ Form validation passed!");
} catch (IllegalArgumentException e) {
System.out.println("✗ Validation failed: " + e.getMessage());
}
}
public static void validateEmail(String email) {
if (!email.contains("@")) {
throw new IllegalArgumentException(
"Email must contain @ symbol"
);
}
if (!email.contains(".")) {
throw new IllegalArgumentException(
"Email must contain a domain (.com, .org, etc.)"
);
}
}
public static void validatePassword(String password) {
if (password.length() < 8) {
throw new IllegalArgumentException(
"Password must be at least 8 characters long"
);
}
}
public static void validateAge(int age) {
if (age < 13) {
throw new IllegalArgumentException(
"Must be at least 13 years old"
);
}
}
}
// Output:
// === Testing Form ===
// Email: alice@email.com
// Password: SecurePass123
// Age: 25
// ✓ Form validation passed!
//
// === Testing Form ===
// Email: invalid-email
// Password: password123
// Age: 25
// ✗ Validation failed: Email must contain @ symbol
//
// === Testing Form ===
// Email: bob@email.com
// Password: 123
// Age: 25
// ✗ Validation failed: Password must be at least 8 characters long
//
// === Testing Form ===
// Email: charlie@email.com
// Password: SecurePass123
// Age: 10
// ✗ Validation failed: Must be at least 13 years old

🔑 Key Concepts

throw - Action

Actually creates and throws an exception

throw new IllegalArgumentException('Invalid input')

throws - Declaration

Declares that method might throw exceptions

public void read() throws IOException

Checked Exceptions

Must be declared with throws or caught

IOException, SQLException must use throws

Unchecked Exceptions

Don't need to be declared

RuntimeException, NullPointerException

Best Practices

  • Use throw to signal errors when they occur
  • Declare exceptions with throws so callers know what to expect
  • Throw specific exception types, not generic Exception
  • Include meaningful error messages when throwing exceptions
  • Don't catch exceptions just to rethrow them without adding value
  • Document why your method throws each exception

💼 Interview Tips

  • Know the difference: throw is inside method, throws is in signature
  • Understand checked vs unchecked exceptions
  • Remember that throws declares multiple exceptions with commas
  • Know that RuntimeException and its subclasses don't need throws
  • Understand exception propagation up the call stack
  • Be able to explain when to throw vs when to handle exceptions