跳到主要内容

Java throw和throws关键字

提示
  1. throws 关键字的用法:用于方法声明中,指明方法可能抛出的异常类型。适用于已检查的异常,如 IOExceptionInvalidClassException
  2. throw 关键字的应用:用于显式抛出单个异常,通常在方法体内使用。适用于抛出具体的异常实例,如 ArithmeticException
  3. 异常类型:Java 异常分为未检查的(如 NullPointerException)和已检查的异常(如 IOException),未检查的异常是由编程错误引起的,通常不需要显式处理。

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

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

参考 Java 异常 来详细了解已检查和未检查的异常。

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

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

Java throws 关键字

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

它的语法是:

accessModifier returnType methodName() throws ExceptionType1, ExceptionType2{
// 代码
}

从上述语法中可以看出,我们可以使用 throws 声明多个异常。

示例 1:Java throws 关键字

import java.io.*;
class Main {
public static void findFile() throws IOException {
// 可能产生 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 (没有这样的文件或目录)

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

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

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

抛出多个异常

下面是我们如何使用 throws 关键字抛出多个异常。

import java.io.*;
class Main {
public static void findFile() throws NullPointerException, IOException, InvalidClassException {

// 可能产生 NullPointerException 的代码
… … …

// 可能产生 IOException 的代码
… … …

// 可能产生 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 子句中指定并处理它不是必需的。

throws 关键字与 try...catch...finally 的区别

可能有许多方法能引发异常。为每个方法编写 try...catch 会非常繁琐,代码会变得冗长且难以阅读。

当你有一个已检查的异常(必须处理的异常),但你不想在当前方法中捕获它时,throws 也是有用的。

Java throw 关键字

throw 关键字用于显式地抛出单个异常。

当异常被抛出时,程序执行的流程会从 try 块转移到 catch 块。我们在方法内部使用 throw 关键字。

它的语法是:

throw throwableObject;

可抛出对象是 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();
}
}


输出

线程 "main" 中的异常 java.lang.ArithmeticException: Trying to divide by 0
Main.divideByZero(Main.java:3)
Main.main(Main.java:7)
退出状态 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("try 块中剩余的代码");
} catch (IOException e) {
System.out.println(e.getMessage());
}
}
}

输出

File not found

findFile() 方法抛出了一个带有我们传递给其构造函数的消息的 IOException

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

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

我们在 main() 方法中处理了这个异常。当异常被抛出时,程序执行的流程从 try 块转移到 catch 块。因此,try 块中的其余代码被跳过,而 catch 块中的语句被执行。