📜  Java throw和throws

📅  最后修改于: 2020-09-26 16:03:39             🧑  作者: Mango

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

 

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

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

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

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

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


Java抛出关键字

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

其语法为:

accessModifier returnType methodName() throws ExceptionType1, ExceptionType2 … {
  // code
}

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


示例1:Java抛出关键字

import java.io.*;
class Main {
  public static void findFile() throws IOException {
    // code that may produce IOException
    File newFile=new File("test.txt");
    FileInputStream stream=new FileInputStream(newFile);
  }

  public static void main(String[] args) {
    try{
      findFile();
    } catch(IOException e){
      System.out.println(e);
    }
  }
}

输出

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

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

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

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


引发多个异常

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

import java.io.*;
class Main {
  public static void findFile() throws NullPointerException, IOException, InvalidClassException {
    
    // code that may produce NullPointerException
    … … … 

    // code that may produce IOException
    … … … 

    // code that may produce InvalidClassException 
    … … … 
  }

  public static void main(String[] args) {
    try{
      findFile();
    } catch(IOException e1){
      System.out.println(e1.getMessage());
    } catch(InvalidClassException e2){
      System.out.println(e2.getMessage());
    }
  }
}

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

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


抛出关键字Vs。尝试…抓住…最后

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

 

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


Java throw关键字

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

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

其语法为:

throw throwableObject;

Throwable对象是Throwable类或Throwable类的子类的实例。


示例2:Java throw关键字

class Main {
  public static void divideByZero() {
    throw new ArithmeticException("Trying to divide by 0");
  }

  public static void main(String[] args) {
    divideByZero();
  }
}

输出

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

在此示例中,我们显式抛出ArithmeticException.

注意: ArithmeticException是未经检查的异常。通常没有必要处理未经检查的异常。


示例3:引发检查的异常

import java.io.*;
class Main {
  public static void findFile() throws IOException {
    throw new IOException("File not found");
  }

  public static void main(String[] args) {
    try {
      findFile();
      System.out.println("Rest of code in try block");
    } catch (IOException e) {
      System.out.println(e.getMessage());
    }
  }
}

输出

File not found

findFile()方法会引发IOException以及我们传递给其构造函数的消息。

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

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

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