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

1.throw

在深入研究之前,让我们先了解一下有关throw关键字的基本知识。

1.1. 句法

要从方法或构造函数抛出异常,请使用throw 关键字和异常类的实例。

public void method() { //an unexpected event occured throw new CustomException("message"); } 

1.2. 处理已检查与未检查的异常

如果我们从方法中抛出未经检查的异常,则不需要处理异常或在throws子句中声明。例如,NullPointerException是一个未经检查的异常。

//处理未经检查的异常不是强制性的 public class JavaExample { public static void main(String[] args) { method(); } public static void method( ) { throw new NullPointerException(); } } 

但是,如果我们使用throw语句抛出已检查的异常,则必须在catch 块中处理异常,或者方法必须使用 throws 声明显式声明它。例如,FileNotFoundException是一个受检查的异常。

//必须处理已检查的异常 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(); } } 

Error在 Java 中,和的每个子类RuntimeException都是未经检查的异常。已检查异常是该类下的所有其他Throwable内容。

1.3. 异常传播

异常从一个方法传播到另一个方法,沿着调用堆栈向上传播,直到被捕获。因此,如果 a() 调用 b(),b() 调用 c(),c() 调用 d(),并且如果 d() 抛出异常,则异常将从 d 传播到 c,再到 b 到 a,除非这些方法之一捕获例外。

异常处理程序的搜索从发生错误的方法开始,并以与调用方法相反的顺序继续遍历调用堆栈,如上所述。

当找到适当的处理程序(catch块)时,运行时系统将异常传递给处理程序。如果未找到异常处理程序,则异常将到达 JVM 的默认异常处理程序,该处理程序将异常详细信息打印到日志并终止应用程序。

2. Throws

Java throws关键字用于声明方法执行过程中可能发生的异常列表。

2.1. 句法

要声明异常列表,请使用throws关键字和异常类名称。

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

2.2. 允许抛出已检查和未检查的异常

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

//可以跳过对未检查异常的处理 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的区别

  • throw关键字用于从任何方法或构造函数显式抛出单个异常,而throws关键字用于方法和构造函数声明中,表示该方法可能抛出哪个异常。
  • throw后面是异常类的实例,而throws后面是异常类名称。
  • throw在方法和构造函数中使用,其中 asthrows与方法和构造函数签名一起使用。
  • 我们throw只能使用 throw 来声明单个异常,但我们可以使用throws其中一个可能会或可能不会通过方法抛出的异常来声明多个异常。
  • 检查的异常会传播到调用者方法,而未检查的异常则不会传播,因此可能不需要显式的异常处理。
  • 使用throw关键字,我们还可以在不使用Break关键字的情况下中断switch 语句或循环,而使用 throws 无法执行这些操作。