一. 异常的种类:
概念: 错误(Error),异常(Exception)
Error:程序无法处理的错误,表示应用程序在运行时出现了严重的错误。 出现这种错误就代表在运行时Java的虚拟机JVM出现了问题。这种错误发生的时候,JVM将会终止线程,因此它不需要程序要去处理它。
Exception:程序可以捕获并且对其进行处理的异常。
RuntimeException:这个类及其子类表示JVM在运行期间可能出现的错误。编译器不会对其进行静态检查。比如:数组访问越界,空指针的使用等。我们可以在程序中选择对其进行捕获或是处理,也可以选择不进行处理,将责任交给client。(顺便提一句,这个情况下unchecked是因为出现的问题都属于程序本身的问题,需要的无非修改代码)
CheckedException:对于这个异常,编译器会对这个类进行检查,如果程序中出现这个类的异常,那么程序员就要对其进行捕获处理,也可以将异常抛出给上层程序,否则无法通过编译。
对比:
二. 异常的使用
throws 与 throw:
这两个关键字容易混淆。我们先看一下它们的使用方式:
throws:当在定义方法使,后面上throws这个关键字(如下面的代码所示)。这就代表这个方法可能会抛出FileNotFoundException这个异常,所以当client对这个方法进行调用时,就需要预测到这个异常可能发生,并且对其进行处理。实际上,很多情况下这是一种偷懒的做法(下面将会告诉你为什么)
public FileInputStream(String name) throws FileNotFoundException{…}
throw:当我们对参数,或者是程序进行的中间结果进行检查时,发生了绝不应该发生的错误时,我们可以人为地throw一个异常(如下面的代码所示)。而我们完全不管这个异常的话,我们就需要在函数名之后放上一个throws,将这个异常交给client来处理。
String readData(Scanner in) throws EOFException
{
. . .
while (. . .){
if (!in.hasNext()) {// EOF encountered
if (n < len)
throw new EOFException(参数);
}
. . .
}
return s;
}
三. 异常的处理
当我们明知某个代码块会抛出异常,并且这个异常是我们可以处理的,我们可以采用try catch的形式,将异常进行捕获并处理(如下面代码所示)。当我们捕获到异常时,我们可以针对捕获的异常进行处理。
try {
code
more code
more code
}
catch (ExceptionType e) {
handler for this type
}
但是常常会有这样的情况,程序员明知这里有异常,但是想不到办法对其进行合理的处理,但是一直卡在这也很影响进度。那么我们可以选择不对这个异常进行处理,而在函数名后面加上一个throws,来告诉调用它的client,这个方法可能会抛出这个异常。
这也就解释了为什么我在上面说“一种偷懒的做法”,因此在使用异常时,我们要遵守这样的原则:尽量在自己这里将异常处理掉,实在不行就要往上传,提醒上家。