throw 和 throws 有啥区别?直接 try catch 不好吗,为啥还要抛呢?

参考回答

throwthrows 的区别

  1. throw
    • throw 用于在方法内部 抛出异常
    • 通常用来手动创建并抛出一个异常对象。
  2. throws
    • throws 用于方法的声明部分,表示该方法 可能抛出异常
    • 调用该方法时,必须处理这些异常(通过 try-catch 或进一步声明 throws)。

直接用 try-catch 不好吗?为什么还要抛?

  • try-catch 适合在 方法内部捕获并处理异常
  • 如果某个方法无法处理异常,或异常应该由调用者处理,则使用 throws 进行抛出。

示例代码:

public class Main {
    public static void main(String[] args) {
        try {
            divide(4, 0); // 调用时捕获异常
        } catch (ArithmeticException e) {
            System.out.println("Exception caught: " + e.getMessage());
        }
    }

    // 方法声明可能抛出异常
    public static int divide(int a, int b) throws ArithmeticException {
        if (b == 0) {
            throw new ArithmeticException("Division by zero is not allowed"); // 抛出异常
        }
        return a / b;
    }
}

输出结果:

Exception caught: Division by zero is not allowed

详细讲解与拓展

1. throw 的详细讲解

  • throw 语句用于 实际抛出异常
  • 它后面必须跟一个异常对象。
  • 常见用法是通过 new 创建异常对象:
throw new IllegalArgumentException("Invalid argument");

注意:

  • 一旦执行到 throw 语句,程序的执行流程会中断,直接跳转到最近的 catch 块。
  • 如果没有捕获异常,程序会终止。

示例:throw 使用

public class Main {
    public static void main(String[] args) {
        checkAge(15);
    }

    public static void checkAge(int age) {
        if (age < 18) {
            throw new IllegalArgumentException("Age must be 18 or above");
        }
        System.out.println("Age is valid");
    }
}

输出结果:

Exception in thread "main" java.lang.IllegalArgumentException: Age must be 18 or above

2. throws 的详细讲解

  • throws 关键字用于方法声明,告诉调用者:这个方法可能抛出异常
  • 它不会实际抛出异常,只是标记一种可能性,异常仍需在方法内部通过 throw 抛出。

示例:throws 使用

public class Main {
    public static void main(String[] args) {
        try {
            readFile("nonexistent.txt");
        } catch (Exception e) {
            System.out.println("Caught exception: " + e.getMessage());
        }
    }

    public static void readFile(String fileName) throws Exception {
        throw new Exception("File not found"); // 抛出异常
    }
}

注意:

  • 如果方法声明了 throws,调用者必须用 try-catch 处理异常,或者在其方法中继续声明 throws

3. 直接用 try-catch 不好吗?为什么还要抛呢?

  1. 异常需要由更高层处理:
    • 某些异常(例如数据库连接失败、文件不存在)需要由调用者或业务逻辑层处理。
    • 直接用 try-catch 捕获后,可能会让异常处理过早,失去了灵活性。

示例:让调用者处理异常

public class Main {
    public static void main(String[] args) {
        try {
            processPayment(500);
        } catch (Exception e) {
            System.out.println("Payment failed: " + e.getMessage());
        }
    }

    public static void processPayment(int amount) throws Exception {
        if (amount > 100) {
            throw new Exception("Amount exceeds limit");
        }
        System.out.println("Payment processed");
    }
}
  1. 逻辑分工:
    • 一些方法负责完成特定功能,异常处理的逻辑应该交给调用者负责。
    • 使用 throws 能让异常在程序中逐层传播,由最终能处理它的代码来解决。
  2. 日志记录与统一处理:
    • 如果所有异常都直接用 try-catch,日志记录和异常处理的逻辑会散布在各处,难以维护。
    • 抛出异常可以让调用链中的高层逻辑进行统一处理。

示例:统一处理异常

public class Main {
    public static void main(String[] args) {
        try {
            service();
        } catch (Exception e) {
            System.out.println("Error occurred: " + e.getMessage());
        }
    }

    public static void service() throws Exception {
        dao(); // 让异常传播到调用者
    }

    public static void dao() throws Exception {
        throw new Exception("Database connection failed");
    }
}

拓展知识

  1. 检查异常和非检查异常
  • 检查异常(Checked Exception)

    • 必须用 throws 声明或 try-catch 捕获。
    • 例如:IOExceptionSQLException
  • 非检查异常(Unchecked Exception)

    • 不需要强制捕获或声明。
    • 例如:NullPointerExceptionIllegalArgumentException
  1. 自定义异常
  • 开发中可以自定义异常,继承 ExceptionRuntimeException
  • 如果继承 Exception,则属于检查异常,必须声明或捕获。
  • 如果继承 RuntimeException,则属于非检查异常,不强制处理。

示例:自定义异常

class CustomException extends Exception {
    public CustomException(String message) {
        super(message);
    }
}

public class Main {
    public static void main(String[] args) {
        try {
            validateInput(-5);
        } catch (CustomException e) {
            System.out.println("Caught exception: " + e.getMessage());
        }
    }

    public static void validateInput(int value) throws CustomException {
        if (value < 0) {
            throw new CustomException("Value cannot be negative");
        }
    }
}

发表回复

后才能评论