Your validation method checks if age is negative. You need to signal "this is wrong" to the caller. throw creates and throws an exception. throws in the signature warns callers what might go wrong.

Throw an exception

Manually trigger an exception.

testAge
ThrowKeyword.java
Replay: real traced execution (multi-file project)
// The throw Keyword

public class ThrowKeyword {
    public static void main(String[] args) {
        System.out.println("=== The throw Keyword ===\n");

        // Basic throw
        System.out.println("--- Basic throw ---");

        int testAge = -5;
        try {
            validateAge(testAge);
        } catch (IllegalArgumentException e) {
            System.out.println("Caught: " + e.getMessage());
        }

        try {
            validateAge(25);
            System.out.println("Age 25 is valid!");
        } catch (IllegalArgumentException e) {
            System.out.println("Error: " + e.getMessage());
        }

        // Throw different exception types
        System.out.println("\n--- Different Exception Types ---");

        testExceptionTypes();

        // Throw with condition
        System.out.println("\n--- Conditional throw ---");

        String[] names = {"Alice", "", "Bob", null};

        for (String name : names) {
            try {
                validateName(name);
                System.out.println("'" + name + "' is valid");
            } catch (IllegalArgumentException e) {
                System.out.println("Invalid name: " + e.getMessage());
            }
        }

        // Throw in constructor
        System.out.println("\n--- Throw in Constructor ---");

        try {
            Person p1 = new Person("John", 30);
            System.out.println("Created: " + p1);

            Person p2 = new Person("", 25);
            System.out.println("Created: " + p2);
        } catch (IllegalArgumentException e) {
            System.out.println("Cannot create Person: " + e.getMessage());
        }

        System.out.println("\n=== Key Points ===");
        System.out.println("""
            1. throw new ExceptionType("message")
            2. throw immediately exits the method
            3. Can throw from anywhere: methods, constructors, blocks
            4. Must throw a Throwable (usually Exception subclass)
            5. Code after throw in same block won't execute
            """);
    }

    static void validateAge(int age) {
        if (age < 0) {
            throw new IllegalArgumentException("Age cannot be negative: " + age);
        }
        if (age > 150) {
            throw new IllegalArgumentException("Age unrealistic: " + age);
        }
        // If we reach here, age is valid
        System.out.println("Validating age: " + age + " - OK");
    }

    static void validateName(String name) {
        if (name == null) {
            throw new IllegalArgumentException("Name cannot be null");
        }
        if (name.isBlank()) {
            throw new IllegalArgumentException("Name cannot be empty");
        }
    }

    static void testExceptionTypes() {
        // Different exception types

        String[] tests = {"null_pointer", "illegal_arg", "illegal_state", "arithmetic"};

        for (String test : tests) {
            try {
                throwSpecificType(test);
            } catch (RuntimeException e) {
                System.out.println(e.getClass().getSimpleName() + ": " + e.getMessage());
            }
        }
    }

    static void throwSpecificType(String type) {
        switch (type) {
            case "null_pointer" -> throw new NullPointerException("Something was null");
            case "illegal_arg" -> throw new IllegalArgumentException("Bad argument");
            case "illegal_state" -> throw new IllegalStateException("Wrong state");
            case "arithmetic" -> throw new ArithmeticException("Math error");
        }
    }
}

class Person {
    String name;
    int age;

    Person(String name, int age) {
        // Validate in constructor
        if (name == null || name.isBlank()) {
            throw new IllegalArgumentException("Name is required");
        }
        if (age < 0 || age > 150) {
            throw new IllegalArgumentException("Invalid age: " + age);
        }
        this.name = name;
        this.age = age;
    }

    @Override
    public String toString() {
        return "Person{name='" + name + "', age=" + age + "}";
    }
}

//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
// The throw Keyword

public class ThrowKeyword {
    public static void main(String[] args) {
        System.out.println("=== The throw Keyword ===\n");

        // Basic throw
        System.out.println("--- Basic throw ---");

        int testAge = 25;
        try {
            validateAge(testAge);
        } catch (IllegalArgumentException e) {
            System.out.println("Caught: " + e.getMessage());
        }

        try {
            validateAge(25);
            System.out.println("Age 25 is valid!");
        } catch (IllegalArgumentException e) {
            System.out.println("Error: " + e.getMessage());
        }

        // Throw different exception types
        System.out.println("\n--- Different Exception Types ---");

        testExceptionTypes();

        // Throw with condition
        System.out.println("\n--- Conditional throw ---");

        String[] names = {"Alice", "", "Bob", null};

        for (String name : names) {
            try {
                validateName(name);
                System.out.println("'" + name + "' is valid");
            } catch (IllegalArgumentException e) {
                System.out.println("Invalid name: " + e.getMessage());
            }
        }

        // Throw in constructor
        System.out.println("\n--- Throw in Constructor ---");

        try {
            Person p1 = new Person("John", 30);
            System.out.println("Created: " + p1);

            Person p2 = new Person("", 25);
            System.out.println("Created: " + p2);
        } catch (IllegalArgumentException e) {
            System.out.println("Cannot create Person: " + e.getMessage());
        }

        System.out.println("\n=== Key Points ===");
        System.out.println("""
            1. throw new ExceptionType("message")
            2. throw immediately exits the method
            3. Can throw from anywhere: methods, constructors, blocks
            4. Must throw a Throwable (usually Exception subclass)
            5. Code after throw in same block won't execute
            """);
    }

    static void validateAge(int age) {
        if (age < 0) {
            throw new IllegalArgumentException("Age cannot be negative: " + age);
        }
        if (age > 150) {
            throw new IllegalArgumentException("Age unrealistic: " + age);
        }
        // If we reach here, age is valid
        System.out.println("Validating age: " + age + " - OK");
    }

    static void validateName(String name) {
        if (name == null) {
            throw new IllegalArgumentException("Name cannot be null");
        }
        if (name.isBlank()) {
            throw new IllegalArgumentException("Name cannot be empty");
        }
    }

    static void testExceptionTypes() {
        // Different exception types

        String[] tests = {"null_pointer", "illegal_arg", "illegal_state", "arithmetic"};

        for (String test : tests) {
            try {
                throwSpecificType(test);
            } catch (RuntimeException e) {
                System.out.println(e.getClass().getSimpleName() + ": " + e.getMessage());
            }
        }
    }

    static void throwSpecificType(String type) {
        switch (type) {
            case "null_pointer" -> throw new NullPointerException("Something was null");
            case "illegal_arg" -> throw new IllegalArgumentException("Bad argument");
            case "illegal_state" -> throw new IllegalStateException("Wrong state");
            case "arithmetic" -> throw new ArithmeticException("Math error");
        }
    }
}

class Person {
    String name;
    int age;

    Person(String name, int age) {
        // Validate in constructor
        if (name == null || name.isBlank()) {
            throw new IllegalArgumentException("Name is required");
        }
        if (age < 0 || age > 150) {
            throw new IllegalArgumentException("Invalid age: " + age);
        }
        this.name = name;
        this.age = age;
    }

    @Override
    public String toString() {
        return "Person{name='" + name + "', age=" + age + "}";
    }
}

//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
// The throw Keyword

public class ThrowKeyword {
    public static void main(String[] args) {
        System.out.println("=== The throw Keyword ===\n");

        // Basic throw
        System.out.println("--- Basic throw ---");

        int testAge = 175;
        try {
            validateAge(testAge);
        } catch (IllegalArgumentException e) {
            System.out.println("Caught: " + e.getMessage());
        }

        try {
            validateAge(25);
            System.out.println("Age 25 is valid!");
        } catch (IllegalArgumentException e) {
            System.out.println("Error: " + e.getMessage());
        }

        // Throw different exception types
        System.out.println("\n--- Different Exception Types ---");

        testExceptionTypes();

        // Throw with condition
        System.out.println("\n--- Conditional throw ---");

        String[] names = {"Alice", "", "Bob", null};

        for (String name : names) {
            try {
                validateName(name);
                System.out.println("'" + name + "' is valid");
            } catch (IllegalArgumentException e) {
                System.out.println("Invalid name: " + e.getMessage());
            }
        }

        // Throw in constructor
        System.out.println("\n--- Throw in Constructor ---");

        try {
            Person p1 = new Person("John", 30);
            System.out.println("Created: " + p1);

            Person p2 = new Person("", 25);
            System.out.println("Created: " + p2);
        } catch (IllegalArgumentException e) {
            System.out.println("Cannot create Person: " + e.getMessage());
        }

        System.out.println("\n=== Key Points ===");
        System.out.println("""
            1. throw new ExceptionType("message")
            2. throw immediately exits the method
            3. Can throw from anywhere: methods, constructors, blocks
            4. Must throw a Throwable (usually Exception subclass)
            5. Code after throw in same block won't execute
            """);
    }

    static void validateAge(int age) {
        if (age < 0) {
            throw new IllegalArgumentException("Age cannot be negative: " + age);
        }
        if (age > 150) {
            throw new IllegalArgumentException("Age unrealistic: " + age);
        }
        // If we reach here, age is valid
        System.out.println("Validating age: " + age + " - OK");
    }

    static void validateName(String name) {
        if (name == null) {
            throw new IllegalArgumentException("Name cannot be null");
        }
        if (name.isBlank()) {
            throw new IllegalArgumentException("Name cannot be empty");
        }
    }

    static void testExceptionTypes() {
        // Different exception types

        String[] tests = {"null_pointer", "illegal_arg", "illegal_state", "arithmetic"};

        for (String test : tests) {
            try {
                throwSpecificType(test);
            } catch (RuntimeException e) {
                System.out.println(e.getClass().getSimpleName() + ": " + e.getMessage());
            }
        }
    }

    static void throwSpecificType(String type) {
        switch (type) {
            case "null_pointer" -> throw new NullPointerException("Something was null");
            case "illegal_arg" -> throw new IllegalArgumentException("Bad argument");
            case "illegal_state" -> throw new IllegalStateException("Wrong state");
            case "arithmetic" -> throw new ArithmeticException("Math error");
        }
    }
}

class Person {
    String name;
    int age;

    Person(String name, int age) {
        // Validate in constructor
        if (name == null || name.isBlank()) {
            throw new IllegalArgumentException("Name is required");
        }
        if (age < 0 || age > 150) {
            throw new IllegalArgumentException("Invalid age: " + age);
        }
        this.name = name;
        this.age = age;
    }

    @Override
    public String toString() {
        return "Person{name='" + name + "', age=" + age + "}";
    }
}

//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
  1. testAge ← -5

    3public class ThrowKeyword {4    public static void main(String[] args) {5        System.out.println("=== The throw Keyword ===\n");67        // Basic throw //?basic_throw8        System.out.println("--- Basic throw ---");910        int testAge→ -5 = -5;  //@testAge=-5, 25, 17511        try { //?try_basic
    output=== The throw Keyword ===
    --- Basic throw ---
  2. try

    10int testAge = -5;  //@testAge=-5, 25, 17511try { //?try_basic12    validateAge(testAge-5); //?call_validate13} catch (IllegalArgumentException e) { //?catch_basic
  3. static void validateAge(int age)

    pass 1 of 2
    66static void validateAge(int age-5) { //?validate_age_method67    if (age < 0) { //?check_negative
  4. if (age < 0)

    66static void validateAge(int age) { //?validate_age_method67    if (age-5 < 0) { //?check_negative68        throw new IllegalArgumentException("Age cannot be negative: " + age); //?throw_negative69    }
  5. catch (IllegalArgumentException e)

    12    validateAge(testAge); //?call_validate13} catch (IllegalArgumentException ejava.lang.IllegalArgumentException: Age cannot be negative: -5) { //?catch_basic14    System.out.println("Caught: " + e.getMessage()); //?print_caught15}
    outputCaught: Age cannot be negative: -5
  6. static void validateAge(int age)

    pass 2 of 2
    17    try { //?try_valid18        validateAge(25); //?call_valid_age19        System.out.println("Age 25 is valid!"); //?age_valid20    } catch (IllegalArgumentException e) { //?catch_valid21        System.out.println("Error: " + e.getMessage()); //?print_error22    }2324    // Throw different exception types //?different_types25    System.out.println("\n--- Different Exception Types ---");2627    testExceptionTypes(); //?call_test_types2829    // Throw with condition //?throw_condition30    System.out.println("\n--- Conditional throw ---");3132    String[] names = {"Alice", "", "Bob", null}; //?names_array3334    for (String name : names) { //?loop_names35        try { //?try_name36            validateName(name); //?validate_name37            System.out.println("'" + name + "' is valid"); //?name_valid38        } catch (IllegalArgumentException e) { //?catch_name39            System.out.println("Invalid name: " + e.getMessage()); //?name_invalid40        }41    }4243    // Throw in constructor //?throw_constructor44    System.out.println("\n--- Throw in Constructor ---");4546    try { //?try_person47        Person p1 = new Person("John", 30); //?create_valid_person48        System.out.println("Created: " + p1); //?print_person4950        Person p2 = new Person("", 25); //?create_invalid_person51        System.out.println("Created: " + p2); //?never_reached52    } catch (IllegalArgumentException e) { //?catch_person53        System.out.println("Cannot create Person: " + e.getMessage()); //?person_error54    }5556    System.out.println("\n=== Key Points ===");57    System.out.println("""58        1. throw new ExceptionType("message")59        2. throw immediately exits the method60        3. Can throw from anywhere: methods, constructors, blocks61        4. Must throw a Throwable (usually Exception subclass)62        5. Code after throw in same block won't execute63        """);64}6566static void validateAge(int age25) { //?validate_age_method67    if (age < 0) { //?check_negative68        throw new IllegalArgumentException("Age cannot be negative: " + age); //?throw_negative69    }70    if (age > 150) { //?check_too_old71        throw new IllegalArgumentException("Age unrealistic: " + age); //?throw_too_old72    }73    // If we reach here, age is valid74    System.out.println("Validating age: " + age25 + " - OK"); //?age_ok75}
    outputValidating age: 25 - OK
    Age 25 is valid!
    
    --- Different Exception Types ---
  7. static void testExceptionTypes()

    86static void testExceptionTypes() { //?test_types_method87    // Different exception types //?diff_types_comment8889    String[] tests = {"null_pointer", "illegal_arg", "illegal_state", "arithmetic"}; //?tests_array
  8. for (String test : tests)

    pass 1 of 4
    91for (String testnull_pointer : tests) { //?loop_tests92    try { //?try_test
    All 4 passes — pass 1 is the card above
    passtestename
    1null_pointer
    2illegal_arg
    3illegal_state
    4arithmeticjava.lang.IllegalArgumentException: Name cannot be emptynull
  9. try

    pass 1 of 4
    91for (String test : tests) { //?loop_tests92    try { //?try_test93        throwSpecificType(testnull_pointer); //?call_throw94    } catch (RuntimeException e) { //?catch_test
    All 4 passes — pass 1 is the card above
    passtestename
    1null_pointer
    2illegal_arg
    3illegal_state
    4arithmeticjava.lang.IllegalArgumentException: Name cannot be emptynull
  10. static void throwSpecificType(String type)

    pass 1 of 4
    100static void throwSpecificType(String typenull_pointer) { //?throw_type_method101    switch (type) { //?switch_type
    All 4 passes — pass 1 is the card above
    passtypeename
    1null_pointer
    2illegal_arg
    3illegal_state
    4arithmeticjava.lang.IllegalArgumentException: Name cannot be emptynull
  11. catch (RuntimeException e)

    pass 1 of 4
    93    throwSpecificType(test); //?call_throw94} catch (RuntimeException ejava.lang.NullPointerException: Something was null) { //?catch_test95    System.out.println(e.getClass().getSimpleName() + ": " + e.getMessage()); //?print_test96}
    outputNullPointerException: Something was null
    All 4 passes — pass 1 is the card above
    passename
    1java.lang.NullPointerException: Something was null
    2java.lang.IllegalArgumentException: Bad argument
    3java.lang.IllegalStateException: Wrong state
    4java.lang.ArithmeticException: Math errornull
  12. for (String name : names)

    pass 1 of 4
    34for (String nameAlice : names) { //?loop_names35    try { //?try_name
    All 4 passes — pass 1 is the card above
    passnamee
    1Alice
    2(empty)java.lang.IllegalArgumentException: Name cannot be empty
    3Bob
    4nulljava.lang.IllegalArgumentException: Name cannot be null
  13. try

    pass 1 of 4
    34for (String name : names) { //?loop_names35    try { //?try_name36        validateName(nameAlice); //?validate_name37        System.out.println("'" + name + "' is valid"); //?name_valid
    All 4 passes — pass 1 is the card above
    passnamee
    1Alice
    2(empty)java.lang.IllegalArgumentException: Name cannot be empty
    3Bob
    4nulljava.lang.IllegalArgumentException: Name cannot be null
  14. static void validateName(String name)

    pass 1 of 4
    35        try { //?try_name36            validateName(nameAlice); //?validate_name37            System.out.println("'" + nameAlice + "' is valid"); //?name_valid38        } catch (IllegalArgumentException e) { //?catch_name39            System.out.println("Invalid name: " + e.getMessage()); //?name_invalid40        }41    }4243    // Throw in constructor //?throw_constructor44    System.out.println("\n--- Throw in Constructor ---");4546    try { //?try_person47        Person p1 = new Person("John", 30); //?create_valid_person48        System.out.println("Created: " + p1); //?print_person4950        Person p2 = new Person("", 25); //?create_invalid_person51        System.out.println("Created: " + p2); //?never_reached52    } catch (IllegalArgumentException e) { //?catch_person53        System.out.println("Cannot create Person: " + e.getMessage()); //?person_error54    }5556    System.out.println("\n=== Key Points ===");57    System.out.println("""58        1. throw new ExceptionType("message")59        2. throw immediately exits the method60        3. Can throw from anywhere: methods, constructors, blocks61        4. Must throw a Throwable (usually Exception subclass)62        5. Code after throw in same block won't execute63        """);64}6566static void validateAge(int age) { //?validate_age_method67    if (age < 0) { //?check_negative68        throw new IllegalArgumentException("Age cannot be negative: " + age); //?throw_negative69    }70    if (age > 150) { //?check_too_old71        throw new IllegalArgumentException("Age unrealistic: " + age); //?throw_too_old72    }73    // If we reach here, age is valid74    System.out.println("Validating age: " + age + " - OK"); //?age_ok75}7677static void validateName(String nameAlice) { //?validate_name_method78    if (name == null) { //?check_null
    output'Alice' is valid
    All 4 passes — pass 1 is the card above
    passnamee
    1Alice
    2(empty)java.lang.IllegalArgumentException: Name cannot be empty
    3Bob
    4nulljava.lang.IllegalArgumentException: Name cannot be null
  15. catch (IllegalArgumentException e)

    pass 1 of 2
    37    System.out.println("'" + name + "' is valid"); //?name_valid38} catch (IllegalArgumentException ejava.lang.IllegalArgumentException: Name cannot be empty) { //?catch_name39    System.out.println("Invalid name: " + e.getMessage()); //?name_invalid40}
    outputInvalid name: Name cannot be empty
  16. if (name == null)

    77static void validateName(String name) { //?validate_name_method78    if (namenull == null) { //?check_null79        throw new IllegalArgumentException("Name cannot be null"); //?throw_null80    }
  17. catch (IllegalArgumentException e)

    pass 2 of 2
    37    System.out.println("'" + name + "' is valid"); //?name_valid38} catch (IllegalArgumentException ejava.lang.IllegalArgumentException: Name cannot be null) { //?catch_name39    System.out.println("Invalid name: " + e.getMessage()); //?name_invalid40}
    outputInvalid name: Name cannot be null
  18. System.out.println(" --- Throw in Constructor ---");

    43// Throw in constructor //?throw_constructor44System.out.println("\n--- Throw in Constructor ---");
    output
    --- Throw in Constructor ---
  19. this.name ← John, this.age ← 30, p1 ← Person{name='John', age=30}

    pass 1 of 2
    46        try { //?try_person47            Person p1→ Person{name='John', age=30} = new Person("John", 30); //?create_valid_person48            System.out.println("Created: " + p1Person{name='John', age=30}); //?print_person4950            Person p2 = new Person("", 25); //?create_invalid_person51            System.out.println("Created: " + p2); //?never_reached52        } catch (IllegalArgumentException e) { //?catch_person53            System.out.println("Cannot create Person: " + e.getMessage()); //?person_error54        }5556        System.out.println("\n=== Key Points ===");57        System.out.println("""58            1. throw new ExceptionType("message")59            2. throw immediately exits the method60            3. Can throw from anywhere: methods, constructors, blocks61            4. Must throw a Throwable (usually Exception subclass)62            5. Code after throw in same block won't execute63            """);64    }6566    static void validateAge(int age) { //?validate_age_method67        if (age < 0) { //?check_negative68            throw new IllegalArgumentException("Age cannot be negative: " + age); //?throw_negative69        }70        if (age > 150) { //?check_too_old71            throw new IllegalArgumentException("Age unrealistic: " + age); //?throw_too_old72        }73        // If we reach here, age is valid74        System.out.println("Validating age: " + age + " - OK"); //?age_ok75    }7677    static void validateName(String name) { //?validate_name_method78        if (name == null) { //?check_null79            throw new IllegalArgumentException("Name cannot be null"); //?throw_null80        }81        if (name.isBlank()) { //?check_blank82            throw new IllegalArgumentException("Name cannot be empty"); //?throw_blank83        }84    }8586    static void testExceptionTypes() { //?test_types_method87        // Different exception types //?diff_types_comment8889        String[] tests = {"null_pointer", "illegal_arg", "illegal_state", "arithmetic"}; //?tests_array9091        for (String test : tests) { //?loop_tests92            try { //?try_test93                throwSpecificType(test); //?call_throw94            } catch (RuntimeException e) { //?catch_test95                System.out.println(e.getClass().getSimpleName() + ": " + e.getMessage()); //?print_test96            }97        }98    }99100    static void throwSpecificType(String type) { //?throw_type_method101        switch (type) { //?switch_type102            case "null_pointer" -> throw new NullPointerException("Something was null"); //?throw_npe103            case "illegal_arg" -> throw new IllegalArgumentException("Bad argument"); //?throw_iae104            case "illegal_state" -> throw new IllegalStateException("Wrong state"); //?throw_ise105            case "arithmetic" -> throw new ArithmeticException("Math error"); //?throw_ae106        }107    }108}109110class Person { //?person_class111    String name; //?person_name112    int age; //?person_age113114    Person(String nameJohn, int age30) { //?person_constructor115        // Validate in constructor //?validate_comment116        if (name == null || name.isBlank()) { //?check_name117            throw new IllegalArgumentException("Name is required"); //?throw_name_error118        }119        if (age < 0 || age > 150) { //?check_age120            throw new IllegalArgumentException("Invalid age: " + age); //?throw_age_error121        }122        this.name→ John = nameJohn; //?set_name123        this.age→ 30 = age30; //?set_age124    }
    outputCreated: Person{name='John', age=30}
  20. Person(String name, int age)

    pass 2 of 2
    114Person(String name(empty), int age25) { //?person_constructor115    // Validate in constructor //?validate_comment
  21. if (name == null || name.isBlank())

    115// Validate in constructor //?validate_comment116if (name(empty) == null || name.isBlank()) { //?check_name117    throw new IllegalArgumentException("Name is required"); //?throw_name_error118}
  22. catch (IllegalArgumentException e)

    51    System.out.println("Created: " + p2); //?never_reached52} catch (IllegalArgumentException ejava.lang.IllegalArgumentException: Name is required) { //?catch_person53    System.out.println("Cannot create Person: " + e.getMessage()); //?person_error54}
    outputCannot create Person: Name is required
  23. System.out.println(" === Key Points ===");

    56    System.out.println("\n=== Key Points ===");57    System.out.println("""58        1. throw new ExceptionType("message")59        2. throw immediately exits the method60        3. Can throw from anywhere: methods, constructors, blocks61        4. Must throw a Throwable (usually Exception subclass)62        5. Code after throw in same block won't execute63        """);64}
    output
    === Key Points ===
    1. throw new ExceptionType("message")
    2. throw immediately exits the method
    3. Can throw from anywhere: methods, constructors, blocks
    4. Must throw a Throwable (usually Exception subclass)
    5. Code after throw in same block won't execute
  1. testAge ← 25

    3public class ThrowKeyword {4    public static void main(String[] args) {5        System.out.println("=== The throw Keyword ===\n");67        // Basic throw8        System.out.println("--- Basic throw ---");910        int testAge→ 25 = 25;11        try {
    output=== The throw Keyword ===
    --- Basic throw ---
  2. try

    10int testAge = 25;11try {12    validateAge(testAge25);13} catch (IllegalArgumentException e) {
  3. static void validateAge(int age)

    pass 1 of 2
    11    try {12        validateAge(testAge25);13    } catch (IllegalArgumentException e) {14        System.out.println("Caught: " + e.getMessage());15    }1617    try {18        validateAge(25);19        System.out.println("Age 25 is valid!");20    } catch (IllegalArgumentException e) {21        System.out.println("Error: " + e.getMessage());22    }2324    // Throw different exception types25    System.out.println("\n--- Different Exception Types ---");2627    testExceptionTypes();2829    // Throw with condition30    System.out.println("\n--- Conditional throw ---");3132    String[] names = {"Alice", "", "Bob", null};3334    for (String name : names) {35        try {36            validateName(name);37            System.out.println("'" + name + "' is valid");38        } catch (IllegalArgumentException e) {39            System.out.println("Invalid name: " + e.getMessage());40        }41    }4243    // Throw in constructor44    System.out.println("\n--- Throw in Constructor ---");4546    try {47        Person p1 = new Person("John", 30);48        System.out.println("Created: " + p1);4950        Person p2 = new Person("", 25);51        System.out.println("Created: " + p2);52    } catch (IllegalArgumentException e) {53        System.out.println("Cannot create Person: " + e.getMessage());54    }5556    System.out.println("\n=== Key Points ===");57    System.out.println("""58        1. throw new ExceptionType("message")59        2. throw immediately exits the method60        3. Can throw from anywhere: methods, constructors, blocks61        4. Must throw a Throwable (usually Exception subclass)62        5. Code after throw in same block won't execute63        """);64}6566static void validateAge(int age25) {67    if (age < 0) {68        throw new IllegalArgumentException("Age cannot be negative: " + age);69    }70    if (age > 150) {71        throw new IllegalArgumentException("Age unrealistic: " + age);72    }73    // If we reach here, age is valid74    System.out.println("Validating age: " + age25 + " - OK");75}
    outputValidating age: 25 - OK
  4. static void validateAge(int age)

    pass 2 of 2
    17    try {18        validateAge(25);19        System.out.println("Age 25 is valid!");20    } catch (IllegalArgumentException e) {21        System.out.println("Error: " + e.getMessage());22    }2324    // Throw different exception types25    System.out.println("\n--- Different Exception Types ---");2627    testExceptionTypes();2829    // Throw with condition30    System.out.println("\n--- Conditional throw ---");3132    String[] names = {"Alice", "", "Bob", null};3334    for (String name : names) {35        try {36            validateName(name);37            System.out.println("'" + name + "' is valid");38        } catch (IllegalArgumentException e) {39            System.out.println("Invalid name: " + e.getMessage());40        }41    }4243    // Throw in constructor44    System.out.println("\n--- Throw in Constructor ---");4546    try {47        Person p1 = new Person("John", 30);48        System.out.println("Created: " + p1);4950        Person p2 = new Person("", 25);51        System.out.println("Created: " + p2);52    } catch (IllegalArgumentException e) {53        System.out.println("Cannot create Person: " + e.getMessage());54    }5556    System.out.println("\n=== Key Points ===");57    System.out.println("""58        1. throw new ExceptionType("message")59        2. throw immediately exits the method60        3. Can throw from anywhere: methods, constructors, blocks61        4. Must throw a Throwable (usually Exception subclass)62        5. Code after throw in same block won't execute63        """);64}6566static void validateAge(int age25) {67    if (age < 0) {68        throw new IllegalArgumentException("Age cannot be negative: " + age);69    }70    if (age > 150) {71        throw new IllegalArgumentException("Age unrealistic: " + age);72    }73    // If we reach here, age is valid74    System.out.println("Validating age: " + age25 + " - OK");75}
    outputValidating age: 25 - OK
    Age 25 is valid!
    
    --- Different Exception Types ---
  5. static void testExceptionTypes()

    86static void testExceptionTypes() {87    // Different exception types8889    String[] tests = {"null_pointer", "illegal_arg", "illegal_state", "arithmetic"};
  6. for (String test : tests)

    pass 1 of 4
    91for (String testnull_pointer : tests) {92    try {
    All 4 passes — pass 1 is the card above
    passtestename
    1null_pointer
    2illegal_arg
    3illegal_state
    4arithmeticjava.lang.IllegalArgumentException: Name cannot be emptynull
  7. try

    pass 1 of 4
    91for (String test : tests) {92    try {93        throwSpecificType(testnull_pointer);94    } catch (RuntimeException e) {
    All 4 passes — pass 1 is the card above
    passtestename
    1null_pointer
    2illegal_arg
    3illegal_state
    4arithmeticjava.lang.IllegalArgumentException: Name cannot be emptynull
  8. static void throwSpecificType(String type)

    pass 1 of 4
    100static void throwSpecificType(String typenull_pointer) {101    switch (type) {
    All 4 passes — pass 1 is the card above
    passtypeename
    1null_pointer
    2illegal_arg
    3illegal_state
    4arithmeticjava.lang.IllegalArgumentException: Name cannot be emptynull
  9. catch (RuntimeException e)

    pass 1 of 4
    93    throwSpecificType(test);94} catch (RuntimeException ejava.lang.NullPointerException: Something was null) {95    System.out.println(e.getClass().getSimpleName() + ": " + e.getMessage());96}
    outputNullPointerException: Something was null
    All 4 passes — pass 1 is the card above
    passename
    1java.lang.NullPointerException: Something was null
    2java.lang.IllegalArgumentException: Bad argument
    3java.lang.IllegalStateException: Wrong state
    4java.lang.ArithmeticException: Math errornull
  10. for (String name : names)

    pass 1 of 4
    34for (String nameAlice : names) {35    try {
    All 4 passes — pass 1 is the card above
    passnamee
    1Alice
    2(empty)java.lang.IllegalArgumentException: Name cannot be empty
    3Bob
    4nulljava.lang.IllegalArgumentException: Name cannot be null
  11. try

    pass 1 of 4
    34for (String name : names) {35    try {36        validateName(nameAlice);37        System.out.println("'" + name + "' is valid");
    All 4 passes — pass 1 is the card above
    passnamee
    1Alice
    2(empty)java.lang.IllegalArgumentException: Name cannot be empty
    3Bob
    4nulljava.lang.IllegalArgumentException: Name cannot be null
  12. static void validateName(String name)

    pass 1 of 4
    35        try {36            validateName(nameAlice);37            System.out.println("'" + nameAlice + "' is valid");38        } catch (IllegalArgumentException e) {39            System.out.println("Invalid name: " + e.getMessage());40        }41    }4243    // Throw in constructor44    System.out.println("\n--- Throw in Constructor ---");4546    try {47        Person p1 = new Person("John", 30);48        System.out.println("Created: " + p1);4950        Person p2 = new Person("", 25);51        System.out.println("Created: " + p2);52    } catch (IllegalArgumentException e) {53        System.out.println("Cannot create Person: " + e.getMessage());54    }5556    System.out.println("\n=== Key Points ===");57    System.out.println("""58        1. throw new ExceptionType("message")59        2. throw immediately exits the method60        3. Can throw from anywhere: methods, constructors, blocks61        4. Must throw a Throwable (usually Exception subclass)62        5. Code after throw in same block won't execute63        """);64}6566static void validateAge(int age) {67    if (age < 0) {68        throw new IllegalArgumentException("Age cannot be negative: " + age);69    }70    if (age > 150) {71        throw new IllegalArgumentException("Age unrealistic: " + age);72    }73    // If we reach here, age is valid74    System.out.println("Validating age: " + age + " - OK");75}7677static void validateName(String nameAlice) {78    if (name == null) {
    output'Alice' is valid
    All 4 passes — pass 1 is the card above
    passnamee
    1Alice
    2(empty)java.lang.IllegalArgumentException: Name cannot be empty
    3Bob
    4nulljava.lang.IllegalArgumentException: Name cannot be null
  13. catch (IllegalArgumentException e)

    pass 1 of 2
    37    System.out.println("'" + name + "' is valid");38} catch (IllegalArgumentException ejava.lang.IllegalArgumentException: Name cannot be empty) {39    System.out.println("Invalid name: " + e.getMessage());40}
    outputInvalid name: Name cannot be empty
  14. if (name == null)

    77static void validateName(String name) {78    if (namenull == null) {79        throw new IllegalArgumentException("Name cannot be null");80    }
  15. catch (IllegalArgumentException e)

    pass 2 of 2
    37    System.out.println("'" + name + "' is valid");38} catch (IllegalArgumentException ejava.lang.IllegalArgumentException: Name cannot be null) {39    System.out.println("Invalid name: " + e.getMessage());40}
    outputInvalid name: Name cannot be null
  16. System.out.println(" --- Throw in Constructor ---");

    43// Throw in constructor44System.out.println("\n--- Throw in Constructor ---");
    output
    --- Throw in Constructor ---
  17. this.name ← John, this.age ← 30, p1 ← Person{name='John', age=30}

    pass 1 of 2
    46        try {47            Person p1→ Person{name='John', age=30} = new Person("John", 30);48            System.out.println("Created: " + p1Person{name='John', age=30});4950            Person p2 = new Person("", 25);51            System.out.println("Created: " + p2);52        } catch (IllegalArgumentException e) {53            System.out.println("Cannot create Person: " + e.getMessage());54        }5556        System.out.println("\n=== Key Points ===");57        System.out.println("""58            1. throw new ExceptionType("message")59            2. throw immediately exits the method60            3. Can throw from anywhere: methods, constructors, blocks61            4. Must throw a Throwable (usually Exception subclass)62            5. Code after throw in same block won't execute63            """);64    }6566    static void validateAge(int age) {67        if (age < 0) {68            throw new IllegalArgumentException("Age cannot be negative: " + age);69        }70        if (age > 150) {71            throw new IllegalArgumentException("Age unrealistic: " + age);72        }73        // If we reach here, age is valid74        System.out.println("Validating age: " + age + " - OK");75    }7677    static void validateName(String name) {78        if (name == null) {79            throw new IllegalArgumentException("Name cannot be null");80        }81        if (name.isBlank()) {82            throw new IllegalArgumentException("Name cannot be empty");83        }84    }8586    static void testExceptionTypes() {87        // Different exception types8889        String[] tests = {"null_pointer", "illegal_arg", "illegal_state", "arithmetic"};9091        for (String test : tests) {92            try {93                throwSpecificType(test);94            } catch (RuntimeException e) {95                System.out.println(e.getClass().getSimpleName() + ": " + e.getMessage());96            }97        }98    }99100    static void throwSpecificType(String type) {101        switch (type) {102            case "null_pointer" -> throw new NullPointerException("Something was null");103            case "illegal_arg" -> throw new IllegalArgumentException("Bad argument");104            case "illegal_state" -> throw new IllegalStateException("Wrong state");105            case "arithmetic" -> throw new ArithmeticException("Math error");106        }107    }108}109110class Person {111    String name;112    int age;113114    Person(String nameJohn, int age30) {115        // Validate in constructor116        if (name == null || name.isBlank()) {117            throw new IllegalArgumentException("Name is required");118        }119        if (age < 0 || age > 150) {120            throw new IllegalArgumentException("Invalid age: " + age);121        }122        this.name→ John = nameJohn;123        this.age→ 30 = age30;124    }
    outputCreated: Person{name='John', age=30}
  18. Person(String name, int age)

    pass 2 of 2
    114Person(String name(empty), int age25) {115    // Validate in constructor
  19. if (name == null || name.isBlank())

    115// Validate in constructor116if (name(empty) == null || name.isBlank()) {117    throw new IllegalArgumentException("Name is required");118}
  20. catch (IllegalArgumentException e)

    51    System.out.println("Created: " + p2);52} catch (IllegalArgumentException ejava.lang.IllegalArgumentException: Name is required) {53    System.out.println("Cannot create Person: " + e.getMessage());54}
    outputCannot create Person: Name is required
  21. System.out.println(" === Key Points ===");

    56    System.out.println("\n=== Key Points ===");57    System.out.println("""58        1. throw new ExceptionType("message")59        2. throw immediately exits the method60        3. Can throw from anywhere: methods, constructors, blocks61        4. Must throw a Throwable (usually Exception subclass)62        5. Code after throw in same block won't execute63        """);64}
    output
    === Key Points ===
    1. throw new ExceptionType("message")
    2. throw immediately exits the method
    3. Can throw from anywhere: methods, constructors, blocks
    4. Must throw a Throwable (usually Exception subclass)
    5. Code after throw in same block won't execute
  1. testAge ← 175

    3public class ThrowKeyword {4    public static void main(String[] args) {5        System.out.println("=== The throw Keyword ===\n");67        // Basic throw8        System.out.println("--- Basic throw ---");910        int testAge→ 175 = 175;11        try {
    output=== The throw Keyword ===
    --- Basic throw ---
  2. try

    10int testAge = 175;11try {12    validateAge(testAge175);13} catch (IllegalArgumentException e) {
  3. static void validateAge(int age)

    pass 1 of 2
    66static void validateAge(int age175) {67    if (age < 0) {
  4. if (age > 150)

    69}70if (age175 > 150) {71    throw new IllegalArgumentException("Age unrealistic: " + age);72}
  5. catch (IllegalArgumentException e)

    12    validateAge(testAge);13} catch (IllegalArgumentException ejava.lang.IllegalArgumentException: Age unrealistic: 175) {14    System.out.println("Caught: " + e.getMessage());15}
    outputCaught: Age unrealistic: 175
  6. static void validateAge(int age)

    pass 2 of 2
    17    try {18        validateAge(25);19        System.out.println("Age 25 is valid!");20    } catch (IllegalArgumentException e) {21        System.out.println("Error: " + e.getMessage());22    }2324    // Throw different exception types25    System.out.println("\n--- Different Exception Types ---");2627    testExceptionTypes();2829    // Throw with condition30    System.out.println("\n--- Conditional throw ---");3132    String[] names = {"Alice", "", "Bob", null};3334    for (String name : names) {35        try {36            validateName(name);37            System.out.println("'" + name + "' is valid");38        } catch (IllegalArgumentException e) {39            System.out.println("Invalid name: " + e.getMessage());40        }41    }4243    // Throw in constructor44    System.out.println("\n--- Throw in Constructor ---");4546    try {47        Person p1 = new Person("John", 30);48        System.out.println("Created: " + p1);4950        Person p2 = new Person("", 25);51        System.out.println("Created: " + p2);52    } catch (IllegalArgumentException e) {53        System.out.println("Cannot create Person: " + e.getMessage());54    }5556    System.out.println("\n=== Key Points ===");57    System.out.println("""58        1. throw new ExceptionType("message")59        2. throw immediately exits the method60        3. Can throw from anywhere: methods, constructors, blocks61        4. Must throw a Throwable (usually Exception subclass)62        5. Code after throw in same block won't execute63        """);64}6566static void validateAge(int age25) {67    if (age < 0) {68        throw new IllegalArgumentException("Age cannot be negative: " + age);69    }70    if (age > 150) {71        throw new IllegalArgumentException("Age unrealistic: " + age);72    }73    // If we reach here, age is valid74    System.out.println("Validating age: " + age25 + " - OK");75}
    outputValidating age: 25 - OK
    Age 25 is valid!
    
    --- Different Exception Types ---
  7. static void testExceptionTypes()

    86static void testExceptionTypes() {87    // Different exception types8889    String[] tests = {"null_pointer", "illegal_arg", "illegal_state", "arithmetic"};
  8. for (String test : tests)

    pass 1 of 4
    91for (String testnull_pointer : tests) {92    try {
    All 4 passes — pass 1 is the card above
    passtestename
    1null_pointer
    2illegal_arg
    3illegal_state
    4arithmeticjava.lang.IllegalArgumentException: Name cannot be emptynull
  9. try

    pass 1 of 4
    91for (String test : tests) {92    try {93        throwSpecificType(testnull_pointer);94    } catch (RuntimeException e) {
    All 4 passes — pass 1 is the card above
    passtestename
    1null_pointer
    2illegal_arg
    3illegal_state
    4arithmeticjava.lang.IllegalArgumentException: Name cannot be emptynull
  10. static void throwSpecificType(String type)

    pass 1 of 4
    100static void throwSpecificType(String typenull_pointer) {101    switch (type) {
    All 4 passes — pass 1 is the card above
    passtypeename
    1null_pointer
    2illegal_arg
    3illegal_state
    4arithmeticjava.lang.IllegalArgumentException: Name cannot be emptynull
  11. catch (RuntimeException e)

    pass 1 of 4
    93    throwSpecificType(test);94} catch (RuntimeException ejava.lang.NullPointerException: Something was null) {95    System.out.println(e.getClass().getSimpleName() + ": " + e.getMessage());96}
    outputNullPointerException: Something was null
    All 4 passes — pass 1 is the card above
    passename
    1java.lang.NullPointerException: Something was null
    2java.lang.IllegalArgumentException: Bad argument
    3java.lang.IllegalStateException: Wrong state
    4java.lang.ArithmeticException: Math errornull
  12. for (String name : names)

    pass 1 of 4
    34for (String nameAlice : names) {35    try {
    All 4 passes — pass 1 is the card above
    passnamee
    1Alice
    2(empty)java.lang.IllegalArgumentException: Name cannot be empty
    3Bob
    4nulljava.lang.IllegalArgumentException: Name cannot be null
  13. try

    pass 1 of 4
    34for (String name : names) {35    try {36        validateName(nameAlice);37        System.out.println("'" + name + "' is valid");
    All 4 passes — pass 1 is the card above
    passnamee
    1Alice
    2(empty)java.lang.IllegalArgumentException: Name cannot be empty
    3Bob
    4nulljava.lang.IllegalArgumentException: Name cannot be null
  14. static void validateName(String name)

    pass 1 of 4
    35        try {36            validateName(nameAlice);37            System.out.println("'" + nameAlice + "' is valid");38        } catch (IllegalArgumentException e) {39            System.out.println("Invalid name: " + e.getMessage());40        }41    }4243    // Throw in constructor44    System.out.println("\n--- Throw in Constructor ---");4546    try {47        Person p1 = new Person("John", 30);48        System.out.println("Created: " + p1);4950        Person p2 = new Person("", 25);51        System.out.println("Created: " + p2);52    } catch (IllegalArgumentException e) {53        System.out.println("Cannot create Person: " + e.getMessage());54    }5556    System.out.println("\n=== Key Points ===");57    System.out.println("""58        1. throw new ExceptionType("message")59        2. throw immediately exits the method60        3. Can throw from anywhere: methods, constructors, blocks61        4. Must throw a Throwable (usually Exception subclass)62        5. Code after throw in same block won't execute63        """);64}6566static void validateAge(int age) {67    if (age < 0) {68        throw new IllegalArgumentException("Age cannot be negative: " + age);69    }70    if (age > 150) {71        throw new IllegalArgumentException("Age unrealistic: " + age);72    }73    // If we reach here, age is valid74    System.out.println("Validating age: " + age + " - OK");75}7677static void validateName(String nameAlice) {78    if (name == null) {
    output'Alice' is valid
    All 4 passes — pass 1 is the card above
    passnamee
    1Alice
    2(empty)java.lang.IllegalArgumentException: Name cannot be empty
    3Bob
    4nulljava.lang.IllegalArgumentException: Name cannot be null
  15. catch (IllegalArgumentException e)

    pass 1 of 2
    37    System.out.println("'" + name + "' is valid");38} catch (IllegalArgumentException ejava.lang.IllegalArgumentException: Name cannot be empty) {39    System.out.println("Invalid name: " + e.getMessage());40}
    outputInvalid name: Name cannot be empty
  16. if (name == null)

    77static void validateName(String name) {78    if (namenull == null) {79        throw new IllegalArgumentException("Name cannot be null");80    }
  17. catch (IllegalArgumentException e)

    pass 2 of 2
    37    System.out.println("'" + name + "' is valid");38} catch (IllegalArgumentException ejava.lang.IllegalArgumentException: Name cannot be null) {39    System.out.println("Invalid name: " + e.getMessage());40}
    outputInvalid name: Name cannot be null
  18. System.out.println(" --- Throw in Constructor ---");

    43// Throw in constructor44System.out.println("\n--- Throw in Constructor ---");
    output
    --- Throw in Constructor ---
  19. this.name ← John, this.age ← 30, p1 ← Person{name='John', age=30}

    pass 1 of 2
    46        try {47            Person p1→ Person{name='John', age=30} = new Person("John", 30);48            System.out.println("Created: " + p1Person{name='John', age=30});4950            Person p2 = new Person("", 25);51            System.out.println("Created: " + p2);52        } catch (IllegalArgumentException e) {53            System.out.println("Cannot create Person: " + e.getMessage());54        }5556        System.out.println("\n=== Key Points ===");57        System.out.println("""58            1. throw new ExceptionType("message")59            2. throw immediately exits the method60            3. Can throw from anywhere: methods, constructors, blocks61            4. Must throw a Throwable (usually Exception subclass)62            5. Code after throw in same block won't execute63            """);64    }6566    static void validateAge(int age) {67        if (age < 0) {68            throw new IllegalArgumentException("Age cannot be negative: " + age);69        }70        if (age > 150) {71            throw new IllegalArgumentException("Age unrealistic: " + age);72        }73        // If we reach here, age is valid74        System.out.println("Validating age: " + age + " - OK");75    }7677    static void validateName(String name) {78        if (name == null) {79            throw new IllegalArgumentException("Name cannot be null");80        }81        if (name.isBlank()) {82            throw new IllegalArgumentException("Name cannot be empty");83        }84    }8586    static void testExceptionTypes() {87        // Different exception types8889        String[] tests = {"null_pointer", "illegal_arg", "illegal_state", "arithmetic"};9091        for (String test : tests) {92            try {93                throwSpecificType(test);94            } catch (RuntimeException e) {95                System.out.println(e.getClass().getSimpleName() + ": " + e.getMessage());96            }97        }98    }99100    static void throwSpecificType(String type) {101        switch (type) {102            case "null_pointer" -> throw new NullPointerException("Something was null");103            case "illegal_arg" -> throw new IllegalArgumentException("Bad argument");104            case "illegal_state" -> throw new IllegalStateException("Wrong state");105            case "arithmetic" -> throw new ArithmeticException("Math error");106        }107    }108}109110class Person {111    String name;112    int age;113114    Person(String nameJohn, int age30) {115        // Validate in constructor116        if (name == null || name.isBlank()) {117            throw new IllegalArgumentException("Name is required");118        }119        if (age < 0 || age > 150) {120            throw new IllegalArgumentException("Invalid age: " + age);121        }122        this.name→ John = nameJohn;123        this.age→ 30 = age30;124    }
    outputCreated: Person{name='John', age=30}
  20. Person(String name, int age)

    pass 2 of 2
    114Person(String name(empty), int age25) {115    // Validate in constructor
  21. if (name == null || name.isBlank())

    115// Validate in constructor116if (name(empty) == null || name.isBlank()) {117    throw new IllegalArgumentException("Name is required");118}
  22. catch (IllegalArgumentException e)

    51    System.out.println("Created: " + p2);52} catch (IllegalArgumentException ejava.lang.IllegalArgumentException: Name is required) {53    System.out.println("Cannot create Person: " + e.getMessage());54}
    outputCannot create Person: Name is required
  23. System.out.println(" === Key Points ===");

    56    System.out.println("\n=== Key Points ===");57    System.out.println("""58        1. throw new ExceptionType("message")59        2. throw immediately exits the method60        3. Can throw from anywhere: methods, constructors, blocks61        4. Must throw a Throwable (usually Exception subclass)62        5. Code after throw in same block won't execute63        """);64}
    output
    === Key Points ===
    1. throw new ExceptionType("message")
    2. throw immediately exits the method
    3. Can throw from anywhere: methods, constructors, blocks
    4. Must throw a Throwable (usually Exception subclass)
    5. Code after throw in same block won't execute

throw new Exception("message") creates and throws immediately.

throw Trigger an exception: `throw new IllegalArgumentException("Invalid")`.

Declare with throws

Tell callers what exceptions a method might throw.

data
ThrowsDeclaration.java
Replay: real traced execution (multi-file project)
// The throws Declaration

import java.io.IOException;
import java.text.ParseException;

public class ThrowsDeclaration {
    public static void main(String[] args) {
        System.out.println("=== The throws Declaration ===\n");

        // Method that throws unchecked exception
        System.out.println("--- Unchecked Exceptions (no throws needed) ---");

        try {
            divideNumbers(10, 0);
        } catch (ArithmeticException e) {
            System.out.println("Caught: " + e.getMessage());
        }

        // Method that throws checked exception
        System.out.println("\n--- Checked Exceptions (throws required) ---");

        try {
            processFile("data.txt");
        } catch (IOException e) {
            System.out.println("Caught IOException: " + e.getMessage());
        }

        // Multiple throws declaration
        System.out.println("\n--- Multiple Exceptions in throws ---");

        String data = "invalid";
        try {
            parseAndProcess(data);
        } catch (IOException e) {
            System.out.println("IO Error: " + e.getMessage());
        } catch (ParseException e) {
            System.out.println("Parse Error: " + e.getMessage());
        }

        // Throws vs handling
        System.out.println("\n--- Throws vs Handling ---");

        demonstrateChoice();

        // Throws in main method
        System.out.println("\n=== throws in main() ===");
        System.out.println("""
            // main can also declare throws:
            public static void main(String[] args) throws IOException {
                // If IOException occurs, program crashes
                // No try-catch needed
            }

            Note: Usually better to catch in main rather than throws.
            """);

        System.out.println("=== Key Points ===");
        System.out.println("""
            1. throws goes in method signature after parameters
            2. Required for checked exceptions (not RuntimeException)
            3. Multiple: throws IOException, ParseException
            4. Caller must catch OR also declare throws
            5. Unchecked exceptions don't require throws
            """);
    }

    // Unchecked - no throws needed
    static int divideNumbers(int a, int b) {
        if (b == 0) {
            throw new ArithmeticException("Division by zero");
        }
        return a / b;
    }

    // Checked - throws required
    static void processFile(String filename) throws IOException {
        System.out.println("Attempting to process: " + filename);

        // Simulating file operation that might fail
        if (!filename.endsWith(".txt")) {
            throw new IOException("Only .txt files supported");
        }

        // Simulate file not found
        if (filename.equals("data.txt")) {
            throw new IOException("File not found: " + filename);
        }

        System.out.println("File processed successfully");
    }

    // Multiple exceptions in throws
    static void parseAndProcess(String data) throws IOException, ParseException {
        System.out.println("Processing data: " + data);

        if (data == null || data.isEmpty()) {
            throw new IOException("No data provided");
        }

        if (!data.matches("\\d+")) {
            throw new ParseException("Data is not numeric: " + data, 0);
        }

        System.out.println("Data valid: " + data);
    }

    static void demonstrateChoice() {
        System.out.println("Option 1: Catch the exception");
        System.out.println("  try { processFile(); } catch (IOException e) { ... }");
        System.out.println();
        System.out.println("Option 2: Propagate with throws");
        System.out.println("  void myMethod() throws IOException { processFile(); }");
        System.out.println();
        System.out.println("Choose based on whether YOU can handle the error,");
        System.out.println("or if the CALLER should handle it.");
    }
}

//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
// The throws Declaration

import java.io.IOException;
import java.text.ParseException;

public class ThrowsDeclaration {
    public static void main(String[] args) {
        System.out.println("=== The throws Declaration ===\n");

        // Method that throws unchecked exception
        System.out.println("--- Unchecked Exceptions (no throws needed) ---");

        try {
            divideNumbers(10, 0);
        } catch (ArithmeticException e) {
            System.out.println("Caught: " + e.getMessage());
        }

        // Method that throws checked exception
        System.out.println("\n--- Checked Exceptions (throws required) ---");

        try {
            processFile("data.txt");
        } catch (IOException e) {
            System.out.println("Caught IOException: " + e.getMessage());
        }

        // Multiple throws declaration
        System.out.println("\n--- Multiple Exceptions in throws ---");

        String data = "123";
        try {
            parseAndProcess(data);
        } catch (IOException e) {
            System.out.println("IO Error: " + e.getMessage());
        } catch (ParseException e) {
            System.out.println("Parse Error: " + e.getMessage());
        }

        // Throws vs handling
        System.out.println("\n--- Throws vs Handling ---");

        demonstrateChoice();

        // Throws in main method
        System.out.println("\n=== throws in main() ===");
        System.out.println("""
            // main can also declare throws:
            public static void main(String[] args) throws IOException {
                // If IOException occurs, program crashes
                // No try-catch needed
            }

            Note: Usually better to catch in main rather than throws.
            """);

        System.out.println("=== Key Points ===");
        System.out.println("""
            1. throws goes in method signature after parameters
            2. Required for checked exceptions (not RuntimeException)
            3. Multiple: throws IOException, ParseException
            4. Caller must catch OR also declare throws
            5. Unchecked exceptions don't require throws
            """);
    }

    // Unchecked - no throws needed
    static int divideNumbers(int a, int b) {
        if (b == 0) {
            throw new ArithmeticException("Division by zero");
        }
        return a / b;
    }

    // Checked - throws required
    static void processFile(String filename) throws IOException {
        System.out.println("Attempting to process: " + filename);

        // Simulating file operation that might fail
        if (!filename.endsWith(".txt")) {
            throw new IOException("Only .txt files supported");
        }

        // Simulate file not found
        if (filename.equals("data.txt")) {
            throw new IOException("File not found: " + filename);
        }

        System.out.println("File processed successfully");
    }

    // Multiple exceptions in throws
    static void parseAndProcess(String data) throws IOException, ParseException {
        System.out.println("Processing data: " + data);

        if (data == null || data.isEmpty()) {
            throw new IOException("No data provided");
        }

        if (!data.matches("\\d+")) {
            throw new ParseException("Data is not numeric: " + data, 0);
        }

        System.out.println("Data valid: " + data);
    }

    static void demonstrateChoice() {
        System.out.println("Option 1: Catch the exception");
        System.out.println("  try { processFile(); } catch (IOException e) { ... }");
        System.out.println();
        System.out.println("Option 2: Propagate with throws");
        System.out.println("  void myMethod() throws IOException { processFile(); }");
        System.out.println();
        System.out.println("Choose based on whether YOU can handle the error,");
        System.out.println("or if the CALLER should handle it.");
    }
}

//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
// The throws Declaration

import java.io.IOException;
import java.text.ParseException;

public class ThrowsDeclaration {
    public static void main(String[] args) {
        System.out.println("=== The throws Declaration ===\n");

        // Method that throws unchecked exception
        System.out.println("--- Unchecked Exceptions (no throws needed) ---");

        try {
            divideNumbers(10, 0);
        } catch (ArithmeticException e) {
            System.out.println("Caught: " + e.getMessage());
        }

        // Method that throws checked exception
        System.out.println("\n--- Checked Exceptions (throws required) ---");

        try {
            processFile("data.txt");
        } catch (IOException e) {
            System.out.println("Caught IOException: " + e.getMessage());
        }

        // Multiple throws declaration
        System.out.println("\n--- Multiple Exceptions in throws ---");

        String data = "";
        try {
            parseAndProcess(data);
        } catch (IOException e) {
            System.out.println("IO Error: " + e.getMessage());
        } catch (ParseException e) {
            System.out.println("Parse Error: " + e.getMessage());
        }

        // Throws vs handling
        System.out.println("\n--- Throws vs Handling ---");

        demonstrateChoice();

        // Throws in main method
        System.out.println("\n=== throws in main() ===");
        System.out.println("""
            // main can also declare throws:
            public static void main(String[] args) throws IOException {
                // If IOException occurs, program crashes
                // No try-catch needed
            }

            Note: Usually better to catch in main rather than throws.
            """);

        System.out.println("=== Key Points ===");
        System.out.println("""
            1. throws goes in method signature after parameters
            2. Required for checked exceptions (not RuntimeException)
            3. Multiple: throws IOException, ParseException
            4. Caller must catch OR also declare throws
            5. Unchecked exceptions don't require throws
            """);
    }

    // Unchecked - no throws needed
    static int divideNumbers(int a, int b) {
        if (b == 0) {
            throw new ArithmeticException("Division by zero");
        }
        return a / b;
    }

    // Checked - throws required
    static void processFile(String filename) throws IOException {
        System.out.println("Attempting to process: " + filename);

        // Simulating file operation that might fail
        if (!filename.endsWith(".txt")) {
            throw new IOException("Only .txt files supported");
        }

        // Simulate file not found
        if (filename.equals("data.txt")) {
            throw new IOException("File not found: " + filename);
        }

        System.out.println("File processed successfully");
    }

    // Multiple exceptions in throws
    static void parseAndProcess(String data) throws IOException, ParseException {
        System.out.println("Processing data: " + data);

        if (data == null || data.isEmpty()) {
            throw new IOException("No data provided");
        }

        if (!data.matches("\\d+")) {
            throw new ParseException("Data is not numeric: " + data, 0);
        }

        System.out.println("Data valid: " + data);
    }

    static void demonstrateChoice() {
        System.out.println("Option 1: Catch the exception");
        System.out.println("  try { processFile(); } catch (IOException e) { ... }");
        System.out.println();
        System.out.println("Option 2: Propagate with throws");
        System.out.println("  void myMethod() throws IOException { processFile(); }");
        System.out.println();
        System.out.println("Choose based on whether YOU can handle the error,");
        System.out.println("or if the CALLER should handle it.");
    }
}

//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
  1. public static void main(String[] args)

    6public class ThrowsDeclaration {7    public static void main(String[] args) {8        System.out.println("=== The throws Declaration ===\n");910        // Method that throws unchecked exception //?unchecked_demo11        System.out.println("--- Unchecked Exceptions (no throws needed) ---");
    output=== The throws Declaration ===
    --- Unchecked Exceptions (no throws needed) ---
  2. static int divideNumbers(int a, int b)

    67// Unchecked - no throws needed //?unchecked_method68static int divideNumbers(int a10, int b0) { //?divide_method69    if (b == 0) { //?check_zero
  3. if (b == 0)

    68static int divideNumbers(int a, int b) { //?divide_method69    if (b0 == 0) { //?check_zero70        throw new ArithmeticException("Division by zero"); //?throw_arithmetic71    }
  4. catch (ArithmeticException e)

    14    divideNumbers(10, 0); //?call_divide15} catch (ArithmeticException ejava.lang.ArithmeticException: Division by zero) { //?catch_unchecked16    System.out.println("Caught: " + e.getMessage()); //?print_unchecked17}
    outputCaught: Division by zero
  5. System.out.println(" --- Checked Exceptions (throws required) ---");

    19// Method that throws checked exception //?checked_demo20System.out.println("\n--- Checked Exceptions (throws required) ---");
    output
    --- Checked Exceptions (throws required) ---
  6. static void processFile(String filename) throws IOException

    75// Checked - throws required //?checked_method76static void processFile(String filenamedata.txt) throws IOException { //?process_method77    System.out.println("Attempting to process: " + filenamedata.txt);
    outputAttempting to process: data.txt
  7. catch (IOException e)

    23    processFile("data.txt"); //?call_process24} catch (IOException ejava.io.IOException: File not found: data.txt) { //?catch_checked25    System.out.println("Caught IOException: " + e.getMessage()); //?print_checked26}
    outputCaught IOException: File not found: data.txt
  8. data ← invalid

    28// Multiple throws declaration //?multiple_throws29System.out.println("\n--- Multiple Exceptions in throws ---");3031String data→ invalid = "invalid";  //@data="invalid", "123", ""32try { //?try_multiple
    output
    --- Multiple Exceptions in throws ---
  9. try

    31String data = "invalid";  //@data="invalid", "123", ""32try { //?try_multiple33    parseAndProcess(datainvalid); //?call_parse34} catch (IOException e) { //?catch_io
  10. static void parseAndProcess(String data) throws IOException, ParseExce…

    92// Multiple exceptions in throws //?multiple_method93static void parseAndProcess(String datainvalid) throws IOException, ParseException { //?parse_method94    System.out.println("Processing data: " + datainvalid);
    outputProcessing data: invalid
  11. catch (ParseException e)

    35    System.out.println("IO Error: " + e.getMessage()); //?print_io36} catch (ParseException ejava.text.ParseException: Data is not numeric: invalid) { //?catch_parse37    System.out.println("Parse Error: " + e.getMessage()); //?print_parse38}
    outputParse Error: Data is not numeric: invalid
  12. System.out.println(" --- Throws vs Handling ---");

    40// Throws vs handling //?throws_vs_handle41System.out.println("\n--- Throws vs Handling ---");4243demonstrateChoice(); //?call_demo_choice
    output
    --- Throws vs Handling ---
  13. static void demonstrateChoice()

    43    demonstrateChoice(); //?call_demo_choice4445    // Throws in main method //?throws_main46    System.out.println("\n=== throws in main() ===");47    System.out.println("""48        // main can also declare throws:49        public static void main(String[] args) throws IOException {50            // If IOException occurs, program crashes51            // No try-catch needed52        }5354        Note: Usually better to catch in main rather than throws.55        """);5657    System.out.println("=== Key Points ===");58    System.out.println("""59        1. throws goes in method signature after parameters60        2. Required for checked exceptions (not RuntimeException)61        3. Multiple: throws IOException, ParseException62        4. Caller must catch OR also declare throws63        5. Unchecked exceptions don't require throws64        """);65}6667// Unchecked - no throws needed //?unchecked_method68static int divideNumbers(int a, int b) { //?divide_method69    if (b == 0) { //?check_zero70        throw new ArithmeticException("Division by zero"); //?throw_arithmetic71    }72    return a / b; //?return_result73}7475// Checked - throws required //?checked_method76static void processFile(String filename) throws IOException { //?process_method77    System.out.println("Attempting to process: " + filename);7879    // Simulating file operation that might fail //?simulate_io80    if (!filename.endsWith(".txt")) { //?check_extension81        throw new IOException("Only .txt files supported"); //?throw_io82    }8384    // Simulate file not found //?simulate_not_found85    if (filename.equals("data.txt")) { //?check_data_txt86        throw new IOException("File not found: " + filename); //?throw_not_found87    }8889    System.out.println("File processed successfully"); //?process_success90}9192// Multiple exceptions in throws //?multiple_method93static void parseAndProcess(String data) throws IOException, ParseException { //?parse_method94    System.out.println("Processing data: " + data);9596    if (data == null || data.isEmpty()) { //?check_null_empty97        throw new IOException("No data provided"); //?throw_io_multi98    }99100    if (!data.matches("\\d+")) { //?check_numeric101        throw new ParseException("Data is not numeric: " + data, 0); //?throw_parse102    }103104    System.out.println("Data valid: " + data); //?data_valid105}106107static void demonstrateChoice() { //?demo_choice_method108    System.out.println("Option 1: Catch the exception");109    System.out.println("  try { processFile(); } catch (IOException e) { ... }");110    System.out.println();111    System.out.println("Option 2: Propagate with throws");112    System.out.println("  void myMethod() throws IOException { processFile(); }");113    System.out.println();114    System.out.println("Choose based on whether YOU can handle the error,");115    System.out.println("or if the CALLER should handle it.");116}
    outputOption 1: Catch the exception
      try { processFile(); } catch (IOException e) { ... }
    Option 2: Propagate with throws
      void myMethod() throws IOException { processFile(); }
    Choose based on whether YOU can handle the error,
    or if the CALLER should handle it.
    
    === throws in main() ===
    // main can also declare throws:
    public static void main(String[] args) throws IOException {
        // If IOException occurs, program crashes
        // No try-catch needed
    }
    
    Note: Usually better to catch in main rather than throws.
    === Key Points ===
    1. throws goes in method signature after parameters
    2. Required for checked exceptions (not RuntimeException)
    3. Multiple: throws IOException, ParseException
    4. Caller must catch OR also declare throws
    5. Unchecked exceptions don't require throws
  1. public static void main(String[] args)

    6public class ThrowsDeclaration {7    public static void main(String[] args) {8        System.out.println("=== The throws Declaration ===\n");910        // Method that throws unchecked exception11        System.out.println("--- Unchecked Exceptions (no throws needed) ---");
    output=== The throws Declaration ===
    --- Unchecked Exceptions (no throws needed) ---
  2. static int divideNumbers(int a, int b)

    67// Unchecked - no throws needed68static int divideNumbers(int a10, int b0) {69    if (b == 0) {
  3. if (b == 0)

    68static int divideNumbers(int a, int b) {69    if (b0 == 0) {70        throw new ArithmeticException("Division by zero");71    }
  4. catch (ArithmeticException e)

    14    divideNumbers(10, 0);15} catch (ArithmeticException ejava.lang.ArithmeticException: Division by zero) {16    System.out.println("Caught: " + e.getMessage());17}
    outputCaught: Division by zero
  5. System.out.println(" --- Checked Exceptions (throws required) ---");

    19// Method that throws checked exception20System.out.println("\n--- Checked Exceptions (throws required) ---");
    output
    --- Checked Exceptions (throws required) ---
  6. static void processFile(String filename) throws IOException

    75// Checked - throws required76static void processFile(String filenamedata.txt) throws IOException {77    System.out.println("Attempting to process: " + filenamedata.txt);
    outputAttempting to process: data.txt
  7. catch (IOException e)

    23    processFile("data.txt");24} catch (IOException ejava.io.IOException: File not found: data.txt) {25    System.out.println("Caught IOException: " + e.getMessage());26}
    outputCaught IOException: File not found: data.txt
  8. data ← 123

    28// Multiple throws declaration29System.out.println("\n--- Multiple Exceptions in throws ---");3031String data→ 123 = "123";32try {
    output
    --- Multiple Exceptions in throws ---
  9. try

    31String data = "123";32try {33    parseAndProcess(data123);34} catch (IOException e) {
  10. static void parseAndProcess(String data) throws IOException, ParseExce…

    32    try {33        parseAndProcess(data123);34    } catch (IOException e) {35        System.out.println("IO Error: " + e.getMessage());36    } catch (ParseException e) {37        System.out.println("Parse Error: " + e.getMessage());38    }3940    // Throws vs handling41    System.out.println("\n--- Throws vs Handling ---");4243    demonstrateChoice();4445    // Throws in main method46    System.out.println("\n=== throws in main() ===");47    System.out.println("""48        // main can also declare throws:49        public static void main(String[] args) throws IOException {50            // If IOException occurs, program crashes51            // No try-catch needed52        }5354        Note: Usually better to catch in main rather than throws.55        """);5657    System.out.println("=== Key Points ===");58    System.out.println("""59        1. throws goes in method signature after parameters60        2. Required for checked exceptions (not RuntimeException)61        3. Multiple: throws IOException, ParseException62        4. Caller must catch OR also declare throws63        5. Unchecked exceptions don't require throws64        """);65}6667// Unchecked - no throws needed68static int divideNumbers(int a, int b) {69    if (b == 0) {70        throw new ArithmeticException("Division by zero");71    }72    return a / b;73}7475// Checked - throws required76static void processFile(String filename) throws IOException {77    System.out.println("Attempting to process: " + filename);7879    // Simulating file operation that might fail80    if (!filename.endsWith(".txt")) {81        throw new IOException("Only .txt files supported");82    }8384    // Simulate file not found85    if (filename.equals("data.txt")) {86        throw new IOException("File not found: " + filename);87    }8889    System.out.println("File processed successfully");90}9192// Multiple exceptions in throws93static void parseAndProcess(String data123) throws IOException, ParseException {94    System.out.println("Processing data: " + data123);9596    if (data == null || data.isEmpty()) {97        throw new IOException("No data provided");98    }99100    if (!data.matches("\\d+")) {101        throw new ParseException("Data is not numeric: " + data, 0);102    }103104    System.out.println("Data valid: " + data123);105}
    outputProcessing data: 123
    Data valid: 123
    
    --- Throws vs Handling ---
  11. static void demonstrateChoice()

    43    demonstrateChoice();4445    // Throws in main method46    System.out.println("\n=== throws in main() ===");47    System.out.println("""48        // main can also declare throws:49        public static void main(String[] args) throws IOException {50            // If IOException occurs, program crashes51            // No try-catch needed52        }5354        Note: Usually better to catch in main rather than throws.55        """);5657    System.out.println("=== Key Points ===");58    System.out.println("""59        1. throws goes in method signature after parameters60        2. Required for checked exceptions (not RuntimeException)61        3. Multiple: throws IOException, ParseException62        4. Caller must catch OR also declare throws63        5. Unchecked exceptions don't require throws64        """);65}6667// Unchecked - no throws needed68static int divideNumbers(int a, int b) {69    if (b == 0) {70        throw new ArithmeticException("Division by zero");71    }72    return a / b;73}7475// Checked - throws required76static void processFile(String filename) throws IOException {77    System.out.println("Attempting to process: " + filename);7879    // Simulating file operation that might fail80    if (!filename.endsWith(".txt")) {81        throw new IOException("Only .txt files supported");82    }8384    // Simulate file not found85    if (filename.equals("data.txt")) {86        throw new IOException("File not found: " + filename);87    }8889    System.out.println("File processed successfully");90}9192// Multiple exceptions in throws93static void parseAndProcess(String data) throws IOException, ParseException {94    System.out.println("Processing data: " + data);9596    if (data == null || data.isEmpty()) {97        throw new IOException("No data provided");98    }99100    if (!data.matches("\\d+")) {101        throw new ParseException("Data is not numeric: " + data, 0);102    }103104    System.out.println("Data valid: " + data);105}106107static void demonstrateChoice() {108    System.out.println("Option 1: Catch the exception");109    System.out.println("  try { processFile(); } catch (IOException e) { ... }");110    System.out.println();111    System.out.println("Option 2: Propagate with throws");112    System.out.println("  void myMethod() throws IOException { processFile(); }");113    System.out.println();114    System.out.println("Choose based on whether YOU can handle the error,");115    System.out.println("or if the CALLER should handle it.");116}
    outputOption 1: Catch the exception
      try { processFile(); } catch (IOException e) { ... }
    Option 2: Propagate with throws
      void myMethod() throws IOException { processFile(); }
    Choose based on whether YOU can handle the error,
    or if the CALLER should handle it.
    
    === throws in main() ===
    // main can also declare throws:
    public static void main(String[] args) throws IOException {
        // If IOException occurs, program crashes
        // No try-catch needed
    }
    
    Note: Usually better to catch in main rather than throws.
    === Key Points ===
    1. throws goes in method signature after parameters
    2. Required for checked exceptions (not RuntimeException)
    3. Multiple: throws IOException, ParseException
    4. Caller must catch OR also declare throws
    5. Unchecked exceptions don't require throws
  1. public static void main(String[] args)

    6public class ThrowsDeclaration {7    public static void main(String[] args) {8        System.out.println("=== The throws Declaration ===\n");910        // Method that throws unchecked exception11        System.out.println("--- Unchecked Exceptions (no throws needed) ---");
    output=== The throws Declaration ===
    --- Unchecked Exceptions (no throws needed) ---
  2. static int divideNumbers(int a, int b)

    67// Unchecked - no throws needed68static int divideNumbers(int a10, int b0) {69    if (b == 0) {
  3. if (b == 0)

    68static int divideNumbers(int a, int b) {69    if (b0 == 0) {70        throw new ArithmeticException("Division by zero");71    }
  4. catch (ArithmeticException e)

    14    divideNumbers(10, 0);15} catch (ArithmeticException ejava.lang.ArithmeticException: Division by zero) {16    System.out.println("Caught: " + e.getMessage());17}
    outputCaught: Division by zero
  5. System.out.println(" --- Checked Exceptions (throws required) ---");

    19// Method that throws checked exception20System.out.println("\n--- Checked Exceptions (throws required) ---");
    output
    --- Checked Exceptions (throws required) ---
  6. static void processFile(String filename) throws IOException

    75// Checked - throws required76static void processFile(String filenamedata.txt) throws IOException {77    System.out.println("Attempting to process: " + filenamedata.txt);
    outputAttempting to process: data.txt
  7. catch (IOException e)

    23    processFile("data.txt");24} catch (IOException ejava.io.IOException: File not found: data.txt) {25    System.out.println("Caught IOException: " + e.getMessage());26}
    outputCaught IOException: File not found: data.txt
  8. data ← (empty)

    28// Multiple throws declaration29System.out.println("\n--- Multiple Exceptions in throws ---");3031String data→ (empty) = "";32try {
    output
    --- Multiple Exceptions in throws ---
  9. try

    31String data = "";32try {33    parseAndProcess(data(empty));34} catch (IOException e) {
  10. static void parseAndProcess(String data) throws IOException, ParseExce…

    92// Multiple exceptions in throws93static void parseAndProcess(String data(empty)) throws IOException, ParseException {94    System.out.println("Processing data: " + data(empty));
    outputProcessing data: 
  11. if (data == null || data.isEmpty())

    96if (data(empty) == null || data.isEmpty()) {97    throw new IOException("No data provided");98}
  12. catch (IOException e)

    33    parseAndProcess(data);34} catch (IOException ejava.io.IOException: No data provided) {35    System.out.println("IO Error: " + e.getMessage());36} catch (ParseException e) {
    outputIO Error: No data provided
  13. System.out.println(" --- Throws vs Handling ---");

    40// Throws vs handling41System.out.println("\n--- Throws vs Handling ---");4243demonstrateChoice();
    output
    --- Throws vs Handling ---
  14. static void demonstrateChoice()

    43    demonstrateChoice();4445    // Throws in main method46    System.out.println("\n=== throws in main() ===");47    System.out.println("""48        // main can also declare throws:49        public static void main(String[] args) throws IOException {50            // If IOException occurs, program crashes51            // No try-catch needed52        }5354        Note: Usually better to catch in main rather than throws.55        """);5657    System.out.println("=== Key Points ===");58    System.out.println("""59        1. throws goes in method signature after parameters60        2. Required for checked exceptions (not RuntimeException)61        3. Multiple: throws IOException, ParseException62        4. Caller must catch OR also declare throws63        5. Unchecked exceptions don't require throws64        """);65}6667// Unchecked - no throws needed68static int divideNumbers(int a, int b) {69    if (b == 0) {70        throw new ArithmeticException("Division by zero");71    }72    return a / b;73}7475// Checked - throws required76static void processFile(String filename) throws IOException {77    System.out.println("Attempting to process: " + filename);7879    // Simulating file operation that might fail80    if (!filename.endsWith(".txt")) {81        throw new IOException("Only .txt files supported");82    }8384    // Simulate file not found85    if (filename.equals("data.txt")) {86        throw new IOException("File not found: " + filename);87    }8889    System.out.println("File processed successfully");90}9192// Multiple exceptions in throws93static void parseAndProcess(String data) throws IOException, ParseException {94    System.out.println("Processing data: " + data);9596    if (data == null || data.isEmpty()) {97        throw new IOException("No data provided");98    }99100    if (!data.matches("\\d+")) {101        throw new ParseException("Data is not numeric: " + data, 0);102    }103104    System.out.println("Data valid: " + data);105}106107static void demonstrateChoice() {108    System.out.println("Option 1: Catch the exception");109    System.out.println("  try { processFile(); } catch (IOException e) { ... }");110    System.out.println();111    System.out.println("Option 2: Propagate with throws");112    System.out.println("  void myMethod() throws IOException { processFile(); }");113    System.out.println();114    System.out.println("Choose based on whether YOU can handle the error,");115    System.out.println("or if the CALLER should handle it.");116}
    outputOption 1: Catch the exception
      try { processFile(); } catch (IOException e) { ... }
    Option 2: Propagate with throws
      void myMethod() throws IOException { processFile(); }
    Choose based on whether YOU can handle the error,
    or if the CALLER should handle it.
    
    === throws in main() ===
    // main can also declare throws:
    public static void main(String[] args) throws IOException {
        // If IOException occurs, program crashes
        // No try-catch needed
    }
    
    Note: Usually better to catch in main rather than throws.
    === Key Points ===
    1. throws goes in method signature after parameters
    2. Required for checked exceptions (not RuntimeException)
    3. Multiple: throws IOException, ParseException
    4. Caller must catch OR also declare throws
    5. Unchecked exceptions don't require throws

void method() throws IOException - caller must handle or declare.

throws Method declaration: `void read() throws IOException`. Compiler enforces handling.

Exception propagation

Exceptions bubble up until caught.

Propagation.java
Replay: real traced execution (multi-file project)
// Exception Propagation

public class Propagation {
    public static void main(String[] args) {
        System.out.println("=== Exception Propagation ===\n");

        // Show the call stack
        System.out.println("Call stack: main() → level1() → level2() → level3()");
        System.out.println();

        // Exception bubbles up
        System.out.println("--- Exception Bubbles Up ---");

        try {
            System.out.println("main: Calling level1()...");
            level1();
            System.out.println("main: level1() returned");
        } catch (RuntimeException e) {
            System.out.println("main: Caught exception!");
            System.out.println("main: Message = " + e.getMessage());
        }

        System.out.println("main: Continuing after catch...\n");

        // Where to catch?
        System.out.println("--- Where Should You Catch? ---");
        demonstrateCatchLevels();

        // Propagation visualization
        System.out.println("\n--- Propagation Visualization ---");
        System.out.println("""
            Call stack (going down):
            ┌─────────────────────┐
            │  main()             │  ← catches here
            │    ↓                │
            │  level1()           │  ← no catch, propagates up
            │    ↓                │
            │  level2()           │  ← no catch, propagates up
            │    ↓                │
            │  level3()           │  ← THROWS exception
            └─────────────────────┘

            Exception propagates (going up):
            level3() → level2() → level1() → main() [CAUGHT]
            """);

        System.out.println("=== Key Points ===");
        System.out.println("""
            1. Exception "bubbles up" the call stack
            2. Each method can catch OR let it propagate
            3. Catch where you can meaningfully handle
            4. If never caught, program crashes
            5. Stack trace shows propagation path
            """);
    }

    static void level1() {
        System.out.println("  level1: Calling level2()...");
        level2();
        System.out.println("  level1: level2() returned");
    }

    static void level2() {
        System.out.println("    level2: Calling level3()...");
        level3();
        System.out.println("    level2: level3() returned");
    }

    static void level3() {
        System.out.println("      level3: About to throw...");
        throw new RuntimeException("Error in level3!");
        // Code below never executes
    }

    static void demonstrateCatchLevels() {
        System.out.println("\nOption 1: Catch at the source (level3)");
        catchAtLevel3();

        System.out.println("\nOption 2: Catch in the middle (level2)");
        catchAtLevel2();

        System.out.println("\nOption 3: Catch at the top (level1)");
        catchAtLevel1();
    }

    static void catchAtLevel3() {
        System.out.println("  Handling error immediately where it occurs");
        try {
            throw new RuntimeException("Error!");
        } catch (RuntimeException e) {
            System.out.println("  Caught in same method: " + e.getMessage());
        }
    }

    static void catchAtLevel2() {
        try {
            doRiskyOperation();
        } catch (RuntimeException e) {
            System.out.println("  Caught one level up: " + e.getMessage());
        }
    }

    static void doRiskyOperation() {
        throw new RuntimeException("Error in risky operation!");
    }

    static void catchAtLevel1() {
        try {
            intermediate();
        } catch (RuntimeException e) {
            System.out.println("  Caught two levels up: " + e.getMessage());
        }
    }

    static void intermediate() {
        deepMethod();
    }

    static void deepMethod() {
        throw new RuntimeException("Error from deep!");
    }
}

//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
  1. public static void main(String[] args)

    3public class Propagation {4    public static void main(String[] args) {5        System.out.println("=== Exception Propagation ===\n");67        // Show the call stack //?show_stack8        System.out.println("Call stack: main() → level1() → level2() → level3()");9        System.out.println();1011        // Exception bubbles up //?bubble_demo12        System.out.println("--- Exception Bubbles Up ---");
    output=== Exception Propagation ===
    Call stack: main() → level1() → level2() → level3()
    --- Exception Bubbles Up ---
  2. try

    14try { //?try_main15    System.out.println("main: Calling level1()..."); //?main_call16    level1(); //?call_level117    System.out.println("main: level1() returned"); //?main_return
    outputmain: Calling level1()...
  3. static void level1()

    57static void level1() { //?level1_method58    System.out.println("  level1: Calling level2()..."); //?level1_call59    level2(); //?call_level260    System.out.println("  level1: level2() returned"); //?level1_return
    output  level1: Calling level2()...
  4. static void level2()

    63static void level2() { //?level2_method64    System.out.println("    level2: Calling level3()..."); //?level2_call65    level3(); //?call_level366    System.out.println("    level2: level3() returned"); //?level2_return
    output    level2: Calling level3()...
  5. static void level3()

    69static void level3() { //?level3_method70    System.out.println("      level3: About to throw..."); //?level3_throw71    throw new RuntimeException("Error in level3!"); //?throw_in_level372    // Code below never executes
    output      level3: About to throw...
  6. catch (RuntimeException e)

    17    System.out.println("main: level1() returned"); //?main_return18} catch (RuntimeException ejava.lang.RuntimeException: Error in level3!) { //?catch_main19    System.out.println("main: Caught exception!"); //?main_caught20    System.out.println("main: Message = " + e.getMessage()); //?main_message21}
    outputmain: Caught exception!
    main: Message = Error in level3!
  7. System.out.println("main: Continuing after catch... "); //?main_contin…

    23System.out.println("main: Continuing after catch...\n"); //?main_continue2425// Where to catch? //?where_catch26System.out.println("--- Where Should You Catch? ---");27demonstrateCatchLevels(); //?call_demo_levels
    outputmain: Continuing after catch...
    --- Where Should You Catch? ---
  8. static void demonstrateCatchLevels()

    75static void demonstrateCatchLevels() { //?demo_levels_method76    System.out.println("\nOption 1: Catch at the source (level3)");77    catchAtLevel3(); //?call_catch_at_3
    output
    Option 1: Catch at the source (level3)
  9. static void catchAtLevel3()

    86static void catchAtLevel3() { //?catch_level3_method87    System.out.println("  Handling error immediately where it occurs");88    try { //?try_at_3
    output  Handling error immediately where it occurs
  10. catch (RuntimeException e)

    76    System.out.println("\nOption 1: Catch at the source (level3)");77    catchAtLevel3(); //?call_catch_at_37879    System.out.println("\nOption 2: Catch in the middle (level2)");80    catchAtLevel2(); //?call_catch_at_28182    System.out.println("\nOption 3: Catch at the top (level1)");83    catchAtLevel1(); //?call_catch_at_184}8586static void catchAtLevel3() { //?catch_level3_method87    System.out.println("  Handling error immediately where it occurs");88    try { //?try_at_389        throw new RuntimeException("Error!"); //?throw_at_390    } catch (RuntimeException ejava.lang.RuntimeException: Error!) { //?catch_at_391        System.out.println("  Caught in same method: " + e.getMessage()); //?caught_at_392    }
    output  Caught in same method: Error!
    
    Option 2: Catch in the middle (level2)
  11. catch (RuntimeException e)

    79    System.out.println("\nOption 2: Catch in the middle (level2)");80    catchAtLevel2(); //?call_catch_at_28182    System.out.println("\nOption 3: Catch at the top (level1)");83    catchAtLevel1(); //?call_catch_at_184}8586static void catchAtLevel3() { //?catch_level3_method87    System.out.println("  Handling error immediately where it occurs");88    try { //?try_at_389        throw new RuntimeException("Error!"); //?throw_at_390    } catch (RuntimeException e) { //?catch_at_391        System.out.println("  Caught in same method: " + e.getMessage()); //?caught_at_392    }93}9495static void catchAtLevel2() { //?catch_level2_method96    try { //?try_at_297        doRiskyOperation(); //?call_risky98    } catch (RuntimeException ejava.lang.RuntimeException: Error in risky operation!) { //?catch_at_299        System.out.println("  Caught one level up: " + e.getMessage()); //?caught_at_2100    }
    output  Caught one level up: Error in risky operation!
    
    Option 3: Catch at the top (level1)
  12. catch (RuntimeException e)

    26    System.out.println("--- Where Should You Catch? ---");27    demonstrateCatchLevels(); //?call_demo_levels2829    // Propagation visualization //?visualization30    System.out.println("\n--- Propagation Visualization ---");31    System.out.println("""32        Call stack (going down):33        ┌─────────────────────┐34        │  main()             │  ← catches here35        │    ↓                │36        │  level1()           │  ← no catch, propagates up37        │    ↓                │38        │  level2()           │  ← no catch, propagates up39        │    ↓                │40        │  level3()           │  ← THROWS exception41        └─────────────────────┘4243        Exception propagates (going up):44        level3() → level2() → level1() → main() [CAUGHT]45        """);4647    System.out.println("=== Key Points ===");48    System.out.println("""49        1. Exception "bubbles up" the call stack50        2. Each method can catch OR let it propagate51        3. Catch where you can meaningfully handle52        4. If never caught, program crashes53        5. Stack trace shows propagation path54        """);55}5657static void level1() { //?level1_method58    System.out.println("  level1: Calling level2()..."); //?level1_call59    level2(); //?call_level260    System.out.println("  level1: level2() returned"); //?level1_return61}6263static void level2() { //?level2_method64    System.out.println("    level2: Calling level3()..."); //?level2_call65    level3(); //?call_level366    System.out.println("    level2: level3() returned"); //?level2_return67}6869static void level3() { //?level3_method70    System.out.println("      level3: About to throw..."); //?level3_throw71    throw new RuntimeException("Error in level3!"); //?throw_in_level372    // Code below never executes73}7475static void demonstrateCatchLevels() { //?demo_levels_method76    System.out.println("\nOption 1: Catch at the source (level3)");77    catchAtLevel3(); //?call_catch_at_37879    System.out.println("\nOption 2: Catch in the middle (level2)");80    catchAtLevel2(); //?call_catch_at_28182    System.out.println("\nOption 3: Catch at the top (level1)");83    catchAtLevel1(); //?call_catch_at_184}8586static void catchAtLevel3() { //?catch_level3_method87    System.out.println("  Handling error immediately where it occurs");88    try { //?try_at_389        throw new RuntimeException("Error!"); //?throw_at_390    } catch (RuntimeException e) { //?catch_at_391        System.out.println("  Caught in same method: " + e.getMessage()); //?caught_at_392    }93}9495static void catchAtLevel2() { //?catch_level2_method96    try { //?try_at_297        doRiskyOperation(); //?call_risky98    } catch (RuntimeException e) { //?catch_at_299        System.out.println("  Caught one level up: " + e.getMessage()); //?caught_at_2100    }101}102103static void doRiskyOperation() { //?risky_method104    throw new RuntimeException("Error in risky operation!"); //?throw_risky105}106107static void catchAtLevel1() { //?catch_level1_method108    try { //?try_at_1109        intermediate(); //?call_intermediate110    } catch (RuntimeException ejava.lang.RuntimeException: Error from deep!) { //?catch_at_1111        System.out.println("  Caught two levels up: " + e.getMessage()); //?caught_at_1112    }
    output  Caught two levels up: Error from deep!
    
    --- Propagation Visualization ---
    Call stack (going down):
    ┌─────────────────────┐
    │  main()             │  ← catches here
    │    ↓                │
    │  level1()           │  ← no catch, propagates up
    │    ↓                │
    │  level2()           │  ← no catch, propagates up
    │    ↓                │
    │  level3()           │  ← THROWS exception
    └─────────────────────┘
    
    Exception propagates (going up):
    level3() → level2() → level1() → main() [CAUGHT]
    === Key Points ===
    1. Exception "bubbles up" the call stack
    2. Each method can catch OR let it propagate
    3. Catch where you can meaningfully handle
    4. If never caught, program crashes
    5. Stack trace shows propagation path

Uncaught exception travels up the call stack to the first handler.

Checked vs unchecked

Some exceptions must be handled, others don't.

CheckedVsUnchecked.java
Replay: real traced execution (multi-file project)
// Checked vs Unchecked Exceptions

import java.io.IOException;

public class CheckedVsUnchecked {
    public static void main(String[] args) {
        System.out.println("=== Checked vs Unchecked Exceptions ===\n");

        // Exception hierarchy
        System.out.println("--- Exception Hierarchy ---");
        System.out.println("""
            Throwable
            ├── Error (don't catch - system errors)
            │   └── OutOfMemoryError, StackOverflowError
            └── Exception
                ├── RuntimeException (UNCHECKED)
                │   ├── NullPointerException
                │   ├── IllegalArgumentException
                │   ├── ArithmeticException
                │   └── IndexOutOfBoundsException
                └── Other Exceptions (CHECKED)
                    ├── IOException
                    ├── SQLException
                    └── ParseException
            """);

        // Unchecked exceptions
        System.out.println("--- Unchecked Exceptions (RuntimeException) ---");
        System.out.println("• No 'throws' required");
        System.out.println("• try-catch is optional");
        System.out.println("• Usually programming errors\n");

        testUnchecked();

        // Checked exceptions
        System.out.println("\n--- Checked Exceptions ---");
        System.out.println("• 'throws' declaration required");
        System.out.println("• Caller MUST catch or declare throws");
        System.out.println("• Usually external failures (IO, network)\n");

        testChecked();

        // Comparison
        System.out.println("\n--- Side-by-Side Comparison ---");

        showComparison();

        System.out.println("\n=== When to Use Which? ===");
        System.out.println("""
            UNCHECKED (RuntimeException):
            • Programming errors (bugs)
            • Invalid arguments
            • Null pointer issues
            • Logic errors

            CHECKED (Exception):
            • External failures
            • File not found
            • Network errors
            • Database connection issues
            • Things caller should be prepared to handle
            """);
    }

    // No throws needed for unchecked
    static void testUnchecked() {
        System.out.println("Method signature: static void testUnchecked()");
        System.out.println("No 'throws' needed!\n");

        // Method that throws unchecked - no declaration
        System.out.println("Calling methods that throw unchecked exceptions:");

        try {
            throwNullPointer();
        } catch (NullPointerException e) {
            System.out.println("  Caught NullPointerException: " + e.getMessage());
        }

        try {
            throwIllegalArg();
        } catch (IllegalArgumentException e) {
            System.out.println("  Caught IllegalArgumentException: " + e.getMessage());
        }
    }

    // No throws in signature
    static void throwNullPointer() {
        throw new NullPointerException("Value was null");
    }

    static void throwIllegalArg() {
        throw new IllegalArgumentException("Bad argument");
    }

    // Throws required for checked
    static void testChecked() {
        System.out.println("Caller must use try-catch OR declare throws\n");

        // Option 1: Use try-catch
        System.out.println("Option 1: try-catch (handle here)");
        try {
            readFile("test.txt");
        } catch (IOException e) {
            System.out.println("  Caught IOException: " + e.getMessage());
        }

        // Option 2 would be: declare throws in method signature
        System.out.println("\nOption 2: Declare 'throws' (propagate to caller)");
        System.out.println("  void myMethod() throws IOException { readFile(); }");
    }

    // throws IOException is REQUIRED
    static void readFile(String filename) throws IOException {
        throw new IOException("Cannot read file: " + filename);
    }

    static void showComparison() {
        System.out.println("""
            ┌────────────────────────────────────────────────────────────┐
            │ Feature              │ Unchecked        │ Checked          │
            ├────────────────────────────────────────────────────────────┤
            │ Base class           │ RuntimeException │ Exception        │
            │ 'throws' required    │ No               │ Yes              │
            │ Catch required       │ No               │ Yes              │
            │ Compiler checks      │ No               │ Yes              │
            │ Typical cause        │ Programming bug  │ External failure │
            │ Example              │ NullPointerEx    │ IOException      │
            └────────────────────────────────────────────────────────────┘
            """);

        // Code comparison
        System.out.println("Code Comparison:");
        System.out.println();
        System.out.println("// UNCHECKED - compiles fine without try-catch:");
        System.out.println("void demo1() {");
        System.out.println("    throw new IllegalArgumentException(\"error\");");
        System.out.println("}");
        System.out.println();
        System.out.println("// CHECKED - compiler error without throws/try-catch:");
        System.out.println("void demo2() throws IOException {  // Must declare!");
        System.out.println("    throw new IOException(\"error\");");
        System.out.println("}");
    }
}

//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
  1. public static void main(String[] args)

    5public class CheckedVsUnchecked {6    public static void main(String[] args) {7        System.out.println("=== Checked vs Unchecked Exceptions ===\n");89        // Exception hierarchy //?hierarchy10        System.out.println("--- Exception Hierarchy ---");11        System.out.println("""12            Throwable13            ├── Error (don't catch - system errors)14            │   └── OutOfMemoryError, StackOverflowError15            └── Exception16                ├── RuntimeException (UNCHECKED)17                │   ├── NullPointerException18                │   ├── IllegalArgumentException19                │   ├── ArithmeticException20                │   └── IndexOutOfBoundsException21                └── Other Exceptions (CHECKED)22                    ├── IOException23                    ├── SQLException24                    └── ParseException25            """);2627        // Unchecked exceptions //?unchecked_section28        System.out.println("--- Unchecked Exceptions (RuntimeException) ---");29        System.out.println("• No 'throws' required");30        System.out.println("• try-catch is optional");31        System.out.println("• Usually programming errors\n");3233        testUnchecked(); //?call_test_unchecked
    output=== Checked vs Unchecked Exceptions ===
    --- Exception Hierarchy ---
    Throwable
    ├── Error (don't catch - system errors)
    │   └── OutOfMemoryError, StackOverflowError
    └── Exception
        ├── RuntimeException (UNCHECKED)
        │   ├── NullPointerException
        │   ├── IllegalArgumentException
        │   ├── ArithmeticException
        │   └── IndexOutOfBoundsException
        └── Other Exceptions (CHECKED)
            ├── IOException
            ├── SQLException
            └── ParseException
    --- Unchecked Exceptions (RuntimeException) ---
    • No 'throws' required
    • try-catch is optional
    • Usually programming errors
  2. static void testUnchecked()

    65// No throws needed for unchecked //?unchecked_methods66static void testUnchecked() { //?test_unchecked_method67    System.out.println("Method signature: static void testUnchecked()");68    System.out.println("No 'throws' needed!\n");6970    // Method that throws unchecked - no declaration //?no_throws71    System.out.println("Calling methods that throw unchecked exceptions:");
    outputMethod signature: static void testUnchecked()
    No 'throws' needed!
    Calling methods that throw unchecked exceptions:
  3. catch (NullPointerException e)

    74    throwNullPointer(); //?call_throw_npe75} catch (NullPointerException ejava.lang.NullPointerException: Value was null) { //?catch_npe76    System.out.println("  Caught NullPointerException: " + e.getMessage()); //?print_npe77}
    output  Caught NullPointerException: Value was null
  4. catch (IllegalArgumentException e)

    33    testUnchecked(); //?call_test_unchecked3435    // Checked exceptions //?checked_section36    System.out.println("\n--- Checked Exceptions ---");37    System.out.println("• 'throws' declaration required");38    System.out.println("• Caller MUST catch or declare throws");39    System.out.println("• Usually external failures (IO, network)\n");4041    testChecked(); //?call_test_checked4243    // Comparison //?comparison44    System.out.println("\n--- Side-by-Side Comparison ---");4546    showComparison(); //?call_comparison4748    System.out.println("\n=== When to Use Which? ===");49    System.out.println("""50        UNCHECKED (RuntimeException):51        • Programming errors (bugs)52        • Invalid arguments53        • Null pointer issues54        • Logic errors5556        CHECKED (Exception):57        • External failures58        • File not found59        • Network errors60        • Database connection issues61        • Things caller should be prepared to handle62        """);63}6465// No throws needed for unchecked //?unchecked_methods66static void testUnchecked() { //?test_unchecked_method67    System.out.println("Method signature: static void testUnchecked()");68    System.out.println("No 'throws' needed!\n");6970    // Method that throws unchecked - no declaration //?no_throws71    System.out.println("Calling methods that throw unchecked exceptions:");7273    try { //?try_unchecked74        throwNullPointer(); //?call_throw_npe75    } catch (NullPointerException e) { //?catch_npe76        System.out.println("  Caught NullPointerException: " + e.getMessage()); //?print_npe77    }7879    try { //?try_unchecked280        throwIllegalArg(); //?call_throw_iae81    } catch (IllegalArgumentException ejava.lang.IllegalArgumentException: Bad argument) { //?catch_iae82        System.out.println("  Caught IllegalArgumentException: " + e.getMessage()); //?print_iae83    }
    output  Caught IllegalArgumentException: Bad argument
    
    --- Checked Exceptions ---
    • 'throws' declaration required
    • Caller MUST catch or declare throws
    • Usually external failures (IO, network)
  5. static void testChecked()

    95// Throws required for checked //?checked_methods96static void testChecked() { //?test_checked_method97    System.out.println("Caller must use try-catch OR declare throws\n");9899    // Option 1: Use try-catch //?option1100    System.out.println("Option 1: try-catch (handle here)");101    try { //?try_checked
    outputCaller must use try-catch OR declare throws
    Option 1: try-catch (handle here)
  6. static void readFile(String filename) throws IOException

    112// throws IOException is REQUIRED //?throws_required113static void readFile(String filenametest.txt) throws IOException { //?read_file_method114    throw new IOException("Cannot read file: " + filename); //?io_throw115}
  7. catch (IOException e)

    102    readFile("test.txt"); //?call_read_file103} catch (IOException ejava.io.IOException: Cannot read file: test.txt) { //?catch_io104    System.out.println("  Caught IOException: " + e.getMessage()); //?print_io105}
    output  Caught IOException: Cannot read file: test.txt
  8. System.out.println(" Option 2: Declare 'throws' (propagate to caller)"…

    41    testChecked(); //?call_test_checked4243    // Comparison //?comparison44    System.out.println("\n--- Side-by-Side Comparison ---");4546    showComparison(); //?call_comparison4748    System.out.println("\n=== When to Use Which? ===");49    System.out.println("""50        UNCHECKED (RuntimeException):51        • Programming errors (bugs)52        • Invalid arguments53        • Null pointer issues54        • Logic errors5556        CHECKED (Exception):57        • External failures58        • File not found59        • Network errors60        • Database connection issues61        • Things caller should be prepared to handle62        """);63}6465// No throws needed for unchecked //?unchecked_methods66static void testUnchecked() { //?test_unchecked_method67    System.out.println("Method signature: static void testUnchecked()");68    System.out.println("No 'throws' needed!\n");6970    // Method that throws unchecked - no declaration //?no_throws71    System.out.println("Calling methods that throw unchecked exceptions:");7273    try { //?try_unchecked74        throwNullPointer(); //?call_throw_npe75    } catch (NullPointerException e) { //?catch_npe76        System.out.println("  Caught NullPointerException: " + e.getMessage()); //?print_npe77    }7879    try { //?try_unchecked280        throwIllegalArg(); //?call_throw_iae81    } catch (IllegalArgumentException e) { //?catch_iae82        System.out.println("  Caught IllegalArgumentException: " + e.getMessage()); //?print_iae83    }84}8586// No throws in signature //?no_throws_comment87static void throwNullPointer() { //?throw_npe_method88    throw new NullPointerException("Value was null"); //?npe_throw89}9091static void throwIllegalArg() { //?throw_iae_method92    throw new IllegalArgumentException("Bad argument"); //?iae_throw93}9495// Throws required for checked //?checked_methods96static void testChecked() { //?test_checked_method97    System.out.println("Caller must use try-catch OR declare throws\n");9899    // Option 1: Use try-catch //?option1100    System.out.println("Option 1: try-catch (handle here)");101    try { //?try_checked102        readFile("test.txt"); //?call_read_file103    } catch (IOException e) { //?catch_io104        System.out.println("  Caught IOException: " + e.getMessage()); //?print_io105    }106107    // Option 2 would be: declare throws in method signature //?option2108    System.out.println("\nOption 2: Declare 'throws' (propagate to caller)");109    System.out.println("  void myMethod() throws IOException { readFile(); }");110}
    output
    Option 2: Declare 'throws' (propagate to caller)
      void myMethod() throws IOException { readFile(); }
    
    --- Side-by-Side Comparison ---
  9. static void showComparison()

    46    showComparison(); //?call_comparison4748    System.out.println("\n=== When to Use Which? ===");49    System.out.println("""50        UNCHECKED (RuntimeException):51        • Programming errors (bugs)52        • Invalid arguments53        • Null pointer issues54        • Logic errors5556        CHECKED (Exception):57        • External failures58        • File not found59        • Network errors60        • Database connection issues61        • Things caller should be prepared to handle62        """);63}6465// No throws needed for unchecked //?unchecked_methods66static void testUnchecked() { //?test_unchecked_method67    System.out.println("Method signature: static void testUnchecked()");68    System.out.println("No 'throws' needed!\n");6970    // Method that throws unchecked - no declaration //?no_throws71    System.out.println("Calling methods that throw unchecked exceptions:");7273    try { //?try_unchecked74        throwNullPointer(); //?call_throw_npe75    } catch (NullPointerException e) { //?catch_npe76        System.out.println("  Caught NullPointerException: " + e.getMessage()); //?print_npe77    }7879    try { //?try_unchecked280        throwIllegalArg(); //?call_throw_iae81    } catch (IllegalArgumentException e) { //?catch_iae82        System.out.println("  Caught IllegalArgumentException: " + e.getMessage()); //?print_iae83    }84}8586// No throws in signature //?no_throws_comment87static void throwNullPointer() { //?throw_npe_method88    throw new NullPointerException("Value was null"); //?npe_throw89}9091static void throwIllegalArg() { //?throw_iae_method92    throw new IllegalArgumentException("Bad argument"); //?iae_throw93}9495// Throws required for checked //?checked_methods96static void testChecked() { //?test_checked_method97    System.out.println("Caller must use try-catch OR declare throws\n");9899    // Option 1: Use try-catch //?option1100    System.out.println("Option 1: try-catch (handle here)");101    try { //?try_checked102        readFile("test.txt"); //?call_read_file103    } catch (IOException e) { //?catch_io104        System.out.println("  Caught IOException: " + e.getMessage()); //?print_io105    }106107    // Option 2 would be: declare throws in method signature //?option2108    System.out.println("\nOption 2: Declare 'throws' (propagate to caller)");109    System.out.println("  void myMethod() throws IOException { readFile(); }");110}111112// throws IOException is REQUIRED //?throws_required113static void readFile(String filename) throws IOException { //?read_file_method114    throw new IOException("Cannot read file: " + filename); //?io_throw115}116117static void showComparison() { //?comparison_method118    System.out.println("""119        ┌────────────────────────────────────────────────────────────┐120        │ Feature              │ Unchecked        │ Checked          │121        ├────────────────────────────────────────────────────────────┤122        │ Base class           │ RuntimeException │ Exception        │123        │ 'throws' required    │ No               │ Yes              │124        │ Catch required       │ No               │ Yes              │125        │ Compiler checks      │ No               │ Yes              │126        │ Typical cause        │ Programming bug  │ External failure │127        │ Example              │ NullPointerEx    │ IOException      │128        └────────────────────────────────────────────────────────────┘129        """);130131    // Code comparison //?code_compare132    System.out.println("Code Comparison:");133    System.out.println();134    System.out.println("// UNCHECKED - compiles fine without try-catch:");135    System.out.println("void demo1() {");136    System.out.println("    throw new IllegalArgumentException(\"error\");");137    System.out.println("}");138    System.out.println();139    System.out.println("// CHECKED - compiler error without throws/try-catch:");140    System.out.println("void demo2() throws IOException {  // Must declare!");141    System.out.println("    throw new IOException(\"error\");");142    System.out.println("}");143}
    output┌────────────────────────────────────────────────────────────┐
    │ Feature              │ Unchecked        │ Checked          │
    ├────────────────────────────────────────────────────────────┤
    │ Base class           │ RuntimeException │ Exception        │
    │ 'throws' required    │ No               │ Yes              │
    │ Catch required       │ No               │ Yes              │
    │ Compiler checks      │ No               │ Yes              │
    │ Typical cause        │ Programming bug  │ External failure │
    │ Example              │ NullPointerEx    │ IOException      │
    └────────────────────────────────────────────────────────────┘
    Code Comparison:
    // UNCHECKED - compiles fine without try-catch:
    void demo1() {
        throw new IllegalArgumentException("error");
    }
    // CHECKED - compiler error without throws/try-catch:
    void demo2() throws IOException {  // Must declare!
        throw new IOException("error");
    }
    
    === When to Use Which? ===
    UNCHECKED (RuntimeException):
    • Programming errors (bugs)
    • Invalid arguments
    • Null pointer issues
    • Logic errors
    
    CHECKED (Exception):
    • External failures
    • File not found
    • Network errors
    • Database connection issues
    • Things caller should be prepared to handle

Checked: must handle or declare (IOException). Unchecked: optional (NullPointerException).

checked exception Compiler requires handling: `IOException`, `SQLException`. Recoverable errors.

Catch, log, rethrow

Handle partially then pass along.

Rethrow.java
Replay: real traced execution (multi-file project)
// Catching, Processing, and Rethrowing

public class Rethrow {
    public static void main(String[] args) {
        System.out.println("=== Catching and Rethrowing ===\n");

        // Simple rethrow
        System.out.println("--- Simple Rethrow ---");

        try {
            simpleRethrow();
        } catch (RuntimeException e) {
            System.out.println("Final catch: " + e.getMessage());
        }

        // Rethrow with additional context
        System.out.println("\n--- Rethrow with Additional Context ---");

        try {
            rethrowWithContext("user123");
        } catch (RuntimeException e) {
            System.out.println("Final catch: " + e.getMessage());
            System.out.println("Cause: " + e.getCause());
        }

        // Rethrow as different type
        System.out.println("\n--- Rethrow as Different Type ---");

        try {
            wrapAndRethrow();
        } catch (RuntimeException e) {
            System.out.println("Exception type: " + e.getClass().getSimpleName());
            System.out.println("Message: " + e.getMessage());
            if (e.getCause() != null) {
                System.out.println("Original cause: " + e.getCause().getClass().getSimpleName());
            }
        }

        // Log and rethrow
        System.out.println("\n--- Log and Rethrow ---");

        try {
            logAndRethrow();
        } catch (RuntimeException e) {
            System.out.println("Handled at top level");
        }

        // Conditional rethrow
        System.out.println("\n--- Conditional Rethrow ---");

        conditionalRethrowDemo();

        System.out.println("\n=== Common Patterns ===");
        System.out.println("""
            1. Log and rethrow (don't swallow)
            2. Wrap in higher-level exception
            3. Add context information
            4. Convert checked to unchecked
            5. Conditional handling
            """);
    }

    static void simpleRethrow() {
        try {
            throw new RuntimeException("Original error");
        } catch (RuntimeException e) {
            System.out.println("Caught, now rethrowing...");
            throw e;
        }
    }

    static void rethrowWithContext(String userId) {
        try {
            processUser(userId);
        } catch (RuntimeException e) {
            // Add context and rethrow
            throw new RuntimeException(
                "Failed to process user: " + userId,
                e  // Original exception as cause
            );
        }
    }

    static void processUser(String userId) {
        throw new RuntimeException("Database connection failed");
    }

    static void wrapAndRethrow() {
        try {
            riskyOperation();
        } catch (IllegalArgumentException e) {
            // Wrap specific exception in more general one
            throw new RuntimeException("Operation failed", e);
        }
    }

    static void riskyOperation() {
        throw new IllegalArgumentException("Invalid input");
    }

    static void logAndRethrow() {
        try {
            performTask();
        } catch (RuntimeException e) {
            // Log the error
            System.out.println("  [LOG] Error occurred: " + e.getMessage());
            System.out.println("  [LOG] Stack trace logged");

            // Rethrow for higher-level handling
            throw e;
        }
    }

    static void performTask() {
        throw new RuntimeException("Task execution error");
    }

    static void conditionalRethrowDemo() {
        int[] errorCodes = {1, 2, 3};

        for (int code : errorCodes) {
            try {
                throwWithCode(code);
            } catch (RuntimeException e) {
                if (code == 2) {
                    // Recoverable - handle and continue
                    System.out.println("Code " + code + ": Handled (recoverable)");
                } else {
                    // Not recoverable - report but continue demo
                    System.out.println("Code " + code + ": " + e.getMessage() + " (would rethrow)");
                    // In real code: throw e;
                }
            }
        }
    }

    static void throwWithCode(int code) {
        throw new RuntimeException("Error code " + code);
    }
}

//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
  1. public static void main(String[] args)

    3public class Rethrow {4    public static void main(String[] args) {5        System.out.println("=== Catching and Rethrowing ===\n");67        // Simple rethrow //?simple_rethrow8        System.out.println("--- Simple Rethrow ---");
    output=== Catching and Rethrowing ===
    --- Simple Rethrow ---
  2. catch (RuntimeException e)

    65    throw new RuntimeException("Original error"); //?throw_original66} catch (RuntimeException ejava.lang.RuntimeException: Original error) { //?catch_in_simple67    System.out.println("Caught, now rethrowing...");68    throw ejava.lang.RuntimeException: Original error; //?rethrow_same69}
    outputCaught, now rethrowing...
  3. catch (RuntimeException e)

    11    simpleRethrow(); //?call_simple12} catch (RuntimeException ejava.lang.RuntimeException: Original error) { //?catch_simple13    System.out.println("Final catch: " + e.getMessage()); //?print_simple14}
    outputFinal catch: Original error
  4. System.out.println(" --- Rethrow with Additional Context ---");

    16// Rethrow with additional context //?add_context17System.out.println("\n--- Rethrow with Additional Context ---");
    output
    --- Rethrow with Additional Context ---
  5. static void rethrowWithContext(String userId)

    72static void rethrowWithContext(String userIduser123) { //?context_method73    try { //?try_in_context
  6. try

    72static void rethrowWithContext(String userId) { //?context_method73    try { //?try_in_context74        processUser(userIduser123); //?call_process_user75    } catch (RuntimeException e) { //?catch_in_context
  7. static void processUser(String userId)

    84static void processUser(String userIduser123) { //?process_user85    throw new RuntimeException("Database connection failed"); //?throw_db_error86}
  8. catch (RuntimeException e)

    74    processUser(userId); //?call_process_user75} catch (RuntimeException ejava.lang.RuntimeException: Database connection failed) { //?catch_in_context76    // Add context and rethrow //?add_context_comment77    throw new RuntimeException( //?throw_with_context78        "Failed to process user: " + userId, //?context_message79        e  // Original exception as cause80    );81}
  9. catch (RuntimeException e)

    20    rethrowWithContext("user123"); //?call_context21} catch (RuntimeException ejava.lang.RuntimeException: Failed to process user: user123) { //?catch_context22    System.out.println("Final catch: " + e.getMessage()); //?print_context_msg23    System.out.println("Cause: " + e.getCause()); //?print_context_cause24}
    outputFinal catch: Failed to process user: user123
    Cause: java.lang.RuntimeException: Database connection failed
  10. System.out.println(" --- Rethrow as Different Type ---");

    26// Rethrow as different type //?change_type27System.out.println("\n--- Rethrow as Different Type ---");
    output
    --- Rethrow as Different Type ---
  11. catch (IllegalArgumentException e)

    90    riskyOperation(); //?call_risky_op91} catch (IllegalArgumentException ejava.lang.IllegalArgumentException: Invalid input) { //?catch_in_wrap92    // Wrap specific exception in more general one //?wrap_comment93    throw new RuntimeException("Operation failed", e); //?throw_wrapped94}
  12. catch (RuntimeException e)

    30    wrapAndRethrow(); //?call_wrap31} catch (RuntimeException ejava.lang.RuntimeException: Operation failed) { //?catch_different32    System.out.println("Exception type: " + e.getClass().getSimpleName()); //?print_type33    System.out.println("Message: " + e.getMessage()); //?print_diff_msg34    if (e.getCause() != null) { //?check_cause
    outputException type: RuntimeException
    Message: Operation failed
  13. if (e.getCause() != null)

    33System.out.println("Message: " + e.getMessage()); //?print_diff_msg34if (e.getCause() != null) { //?check_cause35    System.out.println("Original cause: " + e.getCause().getClass().getSimpleName()); //?print_cause36}
    outputOriginal cause: IllegalArgumentException
  14. System.out.println(" --- Log and Rethrow ---");

    39// Log and rethrow //?log_rethrow40System.out.println("\n--- Log and Rethrow ---");
    output
    --- Log and Rethrow ---
  15. catch (RuntimeException e)

    103    performTask(); //?call_perform104} catch (RuntimeException ejava.lang.RuntimeException: Task execution error) { //?catch_in_log105    // Log the error //?log_comment106    System.out.println("  [LOG] Error occurred: " + e.getMessage()); //?log_error107    System.out.println("  [LOG] Stack trace logged"); //?log_stack108109    // Rethrow for higher-level handling //?rethrow_comment110    throw ejava.lang.RuntimeException: Task execution error; //?rethrow_logged111}
    output  [LOG] Error occurred: Task execution error
      [LOG] Stack trace logged
  16. catch (RuntimeException e)

    43    logAndRethrow(); //?call_log44} catch (RuntimeException ejava.lang.RuntimeException: Task execution error) { //?catch_log45    System.out.println("Handled at top level"); //?print_log46}
    outputHandled at top level
  17. System.out.println(" --- Conditional Rethrow ---");

    48// Conditional rethrow //?conditional49System.out.println("\n--- Conditional Rethrow ---");5051conditionalRethrowDemo(); //?call_conditional
    output
    --- Conditional Rethrow ---
  18. static void conditionalRethrowDemo()

    118static void conditionalRethrowDemo() { //?conditional_demo119    int[] errorCodes = {1, 2, 3}; //?error_codes
  19. for (int code : errorCodes)

    pass 1 of 3
    121for (int code1 : errorCodes) { //?loop_codes122    try { //?try_in_cond
    All 3 passes — pass 1 is the card above
    passcode
    11
    22
    33
  20. try

    pass 1 of 3
    121for (int code : errorCodes) { //?loop_codes122    try { //?try_in_cond123        throwWithCode(code1); //?call_with_code124    } catch (RuntimeException e) { //?catch_in_cond
    All 3 passes — pass 1 is the card above
    passcode
    11
    22
    33
  21. static void throwWithCode(int code)

    pass 1 of 3
    137static void throwWithCode(int code1) { //?throw_with_code138    throw new RuntimeException("Error code " + code); //?throw_code139}
    All 3 passes — pass 1 is the card above
    passcode
    11
    22
    33
  22. catch (RuntimeException e)

    pass 1 of 3
    123    throwWithCode(code); //?call_with_code124} catch (RuntimeException ejava.lang.RuntimeException: Error code 1) { //?catch_in_cond125    if (code == 2) { //?check_recoverable
    All 3 passes — pass 1 is the card above
    passecode
    1java.lang.RuntimeException: Error code 11
    2java.lang.RuntimeException: Error code 22
    3java.lang.RuntimeException: Error code 33
  23. else

    pass 1 of 2
    127    System.out.println("Code " + code + ": Handled (recoverable)"); //?print_recovered128} else { //?else_fatal129    // Not recoverable - report but continue demo //?fatal_comment130    System.out.println("Code " + code1 + ": " + e.getMessage() + " (would rethrow)"); //?print_fatal131    // In real code: throw e;
    outputCode 1: Error code 1 (would rethrow)
  24. if (code == 2)

    124} catch (RuntimeException e) { //?catch_in_cond125    if (code2 == 2) { //?check_recoverable126        // Recoverable - handle and continue //?recoverable_comment127        System.out.println("Code " + code2 + ": Handled (recoverable)"); //?print_recovered128    } else { //?else_fatal
    outputCode 2: Handled (recoverable)
  25. else

    pass 2 of 2
    51    conditionalRethrowDemo(); //?call_conditional5253    System.out.println("\n=== Common Patterns ===");54    System.out.println("""55        1. Log and rethrow (don't swallow)56        2. Wrap in higher-level exception57        3. Add context information58        4. Convert checked to unchecked59        5. Conditional handling60        """);61}6263static void simpleRethrow() { //?simple_rethrow_method64    try { //?try_in_simple65        throw new RuntimeException("Original error"); //?throw_original66    } catch (RuntimeException e) { //?catch_in_simple67        System.out.println("Caught, now rethrowing...");68        throw e; //?rethrow_same69    }70}7172static void rethrowWithContext(String userId) { //?context_method73    try { //?try_in_context74        processUser(userId); //?call_process_user75    } catch (RuntimeException e) { //?catch_in_context76        // Add context and rethrow //?add_context_comment77        throw new RuntimeException( //?throw_with_context78            "Failed to process user: " + userId, //?context_message79            e  // Original exception as cause80        );81    }82}8384static void processUser(String userId) { //?process_user85    throw new RuntimeException("Database connection failed"); //?throw_db_error86}8788static void wrapAndRethrow() { //?wrap_method89    try { //?try_in_wrap90        riskyOperation(); //?call_risky_op91    } catch (IllegalArgumentException e) { //?catch_in_wrap92        // Wrap specific exception in more general one //?wrap_comment93        throw new RuntimeException("Operation failed", e); //?throw_wrapped94    }95}9697static void riskyOperation() { //?risky_op98    throw new IllegalArgumentException("Invalid input"); //?throw_invalid99}100101static void logAndRethrow() { //?log_method102    try { //?try_in_log103        performTask(); //?call_perform104    } catch (RuntimeException e) { //?catch_in_log105        // Log the error //?log_comment106        System.out.println("  [LOG] Error occurred: " + e.getMessage()); //?log_error107        System.out.println("  [LOG] Stack trace logged"); //?log_stack108109        // Rethrow for higher-level handling //?rethrow_comment110        throw e; //?rethrow_logged111    }112}113114static void performTask() { //?perform_task115    throw new RuntimeException("Task execution error"); //?throw_task_error116}117118static void conditionalRethrowDemo() { //?conditional_demo119    int[] errorCodes = {1, 2, 3}; //?error_codes120121    for (int code : errorCodes) { //?loop_codes122        try { //?try_in_cond123            throwWithCode(code); //?call_with_code124        } catch (RuntimeException e) { //?catch_in_cond125            if (code == 2) { //?check_recoverable126                // Recoverable - handle and continue //?recoverable_comment127                System.out.println("Code " + code + ": Handled (recoverable)"); //?print_recovered128            } else { //?else_fatal129                // Not recoverable - report but continue demo //?fatal_comment130                System.out.println("Code " + code3 + ": " + e.getMessage() + " (would rethrow)"); //?print_fatal131                // In real code: throw e;
    outputCode 3: Error code 3 (would rethrow)
    
    === Common Patterns ===
    1. Log and rethrow (don't swallow)
    2. Wrap in higher-level exception
    3. Add context information
    4. Convert checked to unchecked
    5. Conditional handling

Catch, do something (log), then throw e to propagate.

Exercise: Practical.java

Build a validation system with proper exception throwing