在Java中,异常可以分为两种类型
- 非受检异常:它们在编译时不会被检查,而是在运行时被检查。例如:
ArithmeticException
、NullPointerException
、ArrayIndexOutOfBoundsException
、Error
类下的异常等。 - 受检异常:它们在编译时会被检查。例如,
IOException
、InterruptedException
等。
请参考Java 异常以详细了解受检异常和非受检异常。
通常,我们不需要处理非受检异常。这是因为非受检异常是由于编程错误引起的。纠正它们而不是处理它们是良好的实践。
本教程将重点介绍如何使用throw
和throws
来处理受检异常。
Java throws 关键字
我们在方法声明中使用throws
关键字来声明其中可能发生的异常类型。
其语法为
accessModifier returnType methodName() throws ExceptionType1, ExceptionType2 … {
// code
}
从上面的语法可以看出,我们可以使用throws
来声明多个异常。
示例 1:Java throws 关键字
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()
方法指定可能会抛出IOException
。main()
方法调用此方法并处理抛出的异常。
抛出多个异常
以下是使用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
子句中指定它可以抛出NullPointerException
、IOException
和InvalidClassException
。
请注意,我们没有处理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();
}
}
输出
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
块中的语句将被执行。
另请阅读