# Java `throw`关键字

> 原文： [https://howtodoinjava.com/java/exception-handling/throw-vs-throws/](https://howtodoinjava.com/java/exception-handling/throw-vs-throws/)

在 Java 异常处理中，`throw关键字用于显式抛出方法或构造器中的异常。`throws`关键字**用于声明该方法或构造器可能抛出的异常列表。

## 1\. Java `throw`关键字

#### 1.1 语法

要从方法或[构造器](https://howtodoinjava.com/oops/java-constructors/)引发异常，请使用[`throw`关键字](https://howtodoinjava.com/java-keywords/)以及异常类的实例。

```java
public void method() 
{
   //throwing an exception
   throw new SomeException("message");
}

```

#### 1.2 处理受检与非受检异常

如果我们从方法中抛出[非受检的异常](https://howtodoinjava.com/java/exception-handling/checked-vs-unchecked-exceptions-in-java/)，则处理该异常或在`throws`子句中声明不是强制性的。 例如，`NullPointerException`是非受检的异常。

```java
public class JavaExample 
{
	public static void main(String[] args) 
	{
		method();
	}

	public static void method( ) {
		throw new NullPointerException();
	}
}

```

但是，如果我们使用`throw`语句抛出受检异常，则必须在`catch`块**中处理该异常，或者必须使用`throws`声明显式地声明该方法。 例如，`FileNotFoundException`是受检异常。

```java
public class JavaExample 
{
	public static void main(String[] args) 
	{
		try 
		{
			method();
		} 
		catch (FileNotFoundException e) 
		{
			e.printStackTrace();
		}
	}

	public static void method( ) throws FileNotFoundException 
	{
		throw new FileNotFoundException();
	}
}

```

在 Java 中，`Error`和`RuntimeException`的每个子类都是非受检的异常。 一个受检的异常是`Throwable`类下的所有其他内容。

#### 1.3 异常传播

在调用栈中，异常会在方法与方法之间传播，直到被捕获为止。 因此，如果`a()`调用`b()`，然后调用`c()`，又调用`d()`，并且如果`d()`抛出异常，则该异常将从`d`传播到`c`到`b`传播到`a`，除非这些方法之一捕获异常。

如上所述，对异常处理程序的搜索从发生错误的方法开始，然后以与调用方法相反的顺序在调用栈中进行。

找到合适的处理程序（[`catch`块](https://howtodoinjava.com/java/exception-handling/try-catch-finally/)）后，运行时系统会将异常传递给处理程序。 如果未找到异常处理程序，则异常到达 JVM 的默认异常处理程序，该程序将异常详细信息打印到日志并终止应用程序。

## 2\. Java `throws`关键字

Java `throws`关键字用于声明方法执行期间可能发生的异常列表。

#### 2.1 语法

要声明异常列表，请使用`throws`关键字以及异常类名称。

```java
public static void method( ) throws FileNotFoundException, ConnectionException {
	//code
}

```

#### 2.2 可以抛出受检和非受检的异常

我们可以使用`throws`子句声明两种类型的异常，即受检和非受检的异常。 但是调用给定方法**必须仅处理受检异常**。 非受检异常的处理是可选的。

```java
public class JavaExample 
{
	public static void main(String[] args) 
	{
		try 
		{
			//Can skip handling of NullPointerException (unchecked exception)
			method();	
		} 
		catch (FileNotFoundException e) 
		{
			e.printStackTrace();
		}
	}

	public static void method( ) throws NullPointerException, FileNotFoundException {
		//code
	}
}

```

## 3\. Java 中`throw`和`throws`之间的区别

1.  `throw`关键字用于从任何方法或构造器中显式抛出单个异常，而`throws`关键字用于方法和构造器声明中，表示该方法可能引发该异常。
2.  `throw`后跟异常类的实例，而`throws`后跟异常类的名称。
3.  `throw`用于方法和构造器，其中`throws`与方法和构造器签名一起使用。
4.  我们可以使用`throw`仅抛出单个异常，但是可以使用`throws`声明多个异常，其中之一可以通过方法抛出也可以不通过方法抛出。
5.  受检的异常将传播到调用方方法，而非受检的异常将不会传播，因此可能不需要显式的异常处理。
6.  使用`throw`关键字，我们还可以中断`switch`语句或循环，而无需使用`break`关键字，使用`throws`无法执行它。

学习愉快！