# Java `throw`

> 原文： [https://www.programiz.com/java-programming/throw-throws](https://www.programiz.com/java-programming/throw-throws)

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

在 Java 中，异常可以分为两种类型：

*   **非受检的异常**：它们不是在编译时检查的，而是在运行时检查的。例如：`ArithmeticException`，`NullPointerException`，`ArrayIndexOutOfBoundsException`，`Error`类下的异常等。
*   **受检的异常**：在编译时检查它们。 例如`IOException`，`InterruptedException`等。

请参阅 [Java 异常](https://www.programiz.com/java-programming/exceptions)，以详细了解已检查和非受检的异常。

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

现在，本教程将重点介绍如何使用`throw`和`throws`处理受检的异常。

* * *

## Java `throws`关键字

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

其语法为：

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

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

* * *

### 示例 1：Java `throws`关键字

```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
java.io.FileNotFoundException: test.txt (No such file or directory) 
```

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

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

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

* * *

### 引发多个异常

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

```java
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`子句中抛出`NullPointerException`，`IOException`和`InvalidClassException`。

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

* * *

### `throws`关键字 Vs `try-catch-finally`

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

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

* * *

## Java `throw`关键字

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

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

它的语法是：

```java
throw throwableObject;
```

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

* * *

### 示例 2：Java `throw`关键字

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

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

**输出**：

```java
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：引发受检异常

```java
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());
    }
  }
} 
```

**输出**：

```java
File not found 
```

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

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

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

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