原文: https://www.programiz.com/java-programming/throw-throws

在本教程中,我们将在示例的帮助下学习使用throwthrows关键字进行异常处理。

在 Java 中,异常可以分为两种类型:

  • 非受检的异常:它们不是在编译时检查的,而是在运行时检查的。例如:ArithmeticExceptionNullPointerExceptionArrayIndexOutOfBoundsExceptionError类下的异常等。
  • 受检的异常:在编译时检查它们。 例如IOExceptionInterruptedException等。

请参阅 Java 异常,以详细了解已检查和非受检的异常。

通常,我们不需要处理非受检的异常。 这是因为由于编程错误而发生了非受检的异常。 并且,纠正它们而不是处理它们是一个好习惯。

现在,本教程将重点介绍如何使用throwthrows处理受检的异常。


Java throws关键字

我们在方法声明中使用throws关键字来声明其中可能发生的异常的类型。

其语法为:

  1. accessModifier returnType methodName() throws ExceptionType1, ExceptionType2 {
  2. // code
  3. }

从上面的语法可以看到,我们可以使用throws声明多个异常。


示例 1:Java throws关键字

  1. import java.io.*;
  2. class Main {
  3. public static void findFile() throws IOException {
  4. // code that may produce IOException
  5. File newFile=new File("test.txt");
  6. FileInputStream stream=new FileInputStream(newFile);
  7. }
  8. public static void main(String[] args) {
  9. try{
  10. findFile();
  11. } catch(IOException e){
  12. System.out.println(e);
  13. }
  14. }
  15. }

输出

  1. java.io.FileNotFoundException: test.txt (No such file or directory)

当我们运行该程序时,如果文件test.txt不存在,则FileInputStream会抛出FileNotFoundException,该文件扩展了IOException类。

如果某个方法不处理异常,则必须在throws子句中指定其中可能发生的异常的类型,以便调用栈中更深的方法可以处理它们或使用throws关键字自己指定它们。

findFile()方法指定可以抛出IOExceptionmain()方法调用此方法并处理抛出的异常。


引发多个异常

这是我们使用throws关键字引发多个异常的方法。

  1. import java.io.*;
  2. class Main {
  3. public static void findFile() throws NullPointerException, IOException, InvalidClassException {
  4. // code that may produce NullPointerException
  5. // code that may produce IOException
  6. // code that may produce InvalidClassException
  7. }
  8. public static void main(String[] args) {
  9. try{
  10. findFile();
  11. } catch(IOException e1){
  12. System.out.println(e1.getMessage());
  13. } catch(InvalidClassException e2){
  14. System.out.println(e2.getMessage());
  15. }
  16. }
  17. }

在这里,findFile()方法指定它可以在其throws子句中抛出NullPointerExceptionIOExceptionInvalidClassException

请注意,我们尚未处理NullPointerException。 这是因为它是非受检的异常。 不必在throws子句中指定它并进行处理。


throws关键字 Vs try-catch-finally

可能有几种方法可能导致异常。 为每种方法编写try...catch将会很繁琐,并且代码变得冗长且可读性较差。

当您检查了不想在当前方法中捕获的异常(必须处理的异常)时,throws也很有用。


Java throw关键字

throw关键字用于显式引发单个异常。

引发异常时,程序执行流程从try块转移到catch块。 我们在方法中使用throw关键字。

它的语法是:

  1. throw throwableObject;

可抛出对象是Throwable类或Throwable类的子类的实例。


示例 2:Java throw关键字

  1. class Main {
  2. public static void divideByZero() {
  3. throw new ArithmeticException("Trying to divide by 0");
  4. }
  5. public static void main(String[] args) {
  6. divideByZero();
  7. }
  8. }

输出

  1. Exception in thread "main" java.lang.ArithmeticException: Trying to divide by 0
  2. at Main.divideByZero(Main.java:3)
  3. at Main.main(Main.java:7)
  4. exit status 1

在此示例中,我们明确抛出了ArithmeticException.

注意ArithmeticException是非受检的异常。 通常没有必要处理非受检的异常。


示例 3:引发受检异常

  1. import java.io.*;
  2. class Main {
  3. public static void findFile() throws IOException {
  4. throw new IOException("File not found");
  5. }
  6. public static void main(String[] args) {
  7. try {
  8. findFile();
  9. System.out.println("Rest of code in try block");
  10. } catch (IOException e) {
  11. System.out.println(e.getMessage());
  12. }
  13. }
  14. }

输出

  1. File not found

findFile()方法会向我们传递给其构造器的消息引发IOException

注意,由于它是一个受检的异常,因此必须在throws子句中指定它。

调用此findFile()方法的方法需要处理此异常,或者自己使用throws关键字指定该异常。

我们已经在main ()方法中处理了此异常。 引发异常时,程序执行流程从try块转移到catch块。 因此,将跳过try块中的其余代码,并执行catch块中的语句。