在本教程中,我们将在示例的帮助下学习使用throw和throws关键字进行异常处理。
在Java中,异常可以分为两种类型:
未检查的异常:它们不是在编译时而是在运行时被检查,例如:ArithmeticException,NullPointerException,ArrayIndexOutOfBoundsException,Error类下的异常等。
检查的异常:在编译时检查它们。例如IOException,InterruptedException等。
请参考Java异常以详细了解已检查和未检查的异常。
通常,我们不需要处理未经检查的异常。这是因为由于编程错误而发生了未经检查的异常。并且,纠正它们而不是处理它们是一个好习惯。
现在,本教程将重点介绍如何使用throw和throws处理已检查的异常。
我们在方法声明中使用throws关键字来声明其中可能发生的异常的类型。
其语法为:
accessModifier returnType methodName() throws ExceptionType1, ExceptionType2 … { // code }
从上面的语法可以看到,我们可以用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 (No such file or directory)
当我们运行这个程序时,如果文件test.txt不存在,FileInputStream将抛出一个继承IOException类的FileNotFoundException异常。
如果方法不处理异常,则必须在throws子句中指定该方法中可能发生的异常类型,以便调用堆栈中更高层的方法可以处理它们或使用throws关键字本身指定它们。
findFile()方法指定可以抛出IOException。 main()方法调用此方法并处理抛出的异常。
这是我们如何使用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子句中抛出NullPointerException、IOException和InvalidClassException。
请注意,我们尚未处理NullPointerException。这是因为它是未经检查的异常。不必在throws子句中指定它并进行处理。
可能有几个方法会导致异常。为每种方法编写try...catch将是乏味的,并且代码将变得冗长且难以理解。
当您已检查了不希望在当前方法中捕获的异常(必须处理的异常)时,throws也很有用。
throw关键字用于显式地抛出一个异常。
当引发异常时,程序执行的流程从try块转移到catch块。我们在方法中使用throw关键字。
其语法为:
throw throwableObject;
Throwable对象是Throwable类或Throwable类的子类的实例。
class Main { public static void divideByZero() { throw new ArithmeticException("试图除以0"); } public static void main(String[] args) { divideByZero(); } }
输出结果
Exception in thread "main" java.lang.ArithmeticException: 试图除以0 at Main.divideByZero(Main.java:3) at Main.main(Main.java:7) exit status 1
在此示例中,我们明确抛出 ArithmeticException.
注意: ArithmeticException是未经检查的异常。通常没有必要处理未经检查的异常。
import java.io.*; class Main { public static void findFile() throws IOException { throw new IOException("文件未找到"); } public static void main(String[] args) { try { findFile(); System.out.println("try块中的其余代码"); } catch (IOException e) { System.out.println(e.getMessage()); } } }
输出结果
文件未找到
findFile()方法使用传递给其构造函数的消息抛出一个IOException。
注意,由于它是一个检查的异常,因此必须在throws子句中指定它。
调用findFile()方法的方法需要处理此异常,或者自己使用throws关键字指定它。
我们已经在main()方法中处理了此异常。引发异常时,程序执行的流程在try块之间转移到catch。因此,将跳过该try块中的其余代码,并执行该catch块中的语句。