异常处理概述
使用返回值状态标识异常
在JAVA语言出现以前,传统的异常处理方式多采用返回值来标识程序出现的异常情况,这种方式虽然为程序员所熟悉,但却有多个坏处。
首先,一个API可以返回任意的返回值,而这些返回值本身并不能解释该返回值是否代表一个异常情况发生了和该异常的具体情況,需要调用API的程序自己判断并解释返回值的含义。
其次,并没有一种机制来保证异常情况一定会得到处理调用程序可以简单的忽略该返回值,需要调用API的程序员记住去检测返回值并处理异常情况。这种方式还让程序代码变得冗长,尤其是当进行操作等容易出现异常情況的处理时,代码的很大部分用于处理异常情况的switch分支,程序代码的可读性变得很差。
异常处理机制
当程序中抛出一个异常后,程序从程序中导致异常的代码处跳出,java虚拟机检测寻找和try关键字匹配的处理该异常的 catch块,如果找到,将控制权交到 catch块中的代码,然后继续往下执行程序,try块中发生异常的代码不会被重新执行。如果没有找到处理该异常的 catch块在所有的 finally.快代码被执行和当前线程的所属的Thread Group(线程组)的 uncaughtexception(未捕获异常)方法被调用后,遇到异常的当前线程被中止。
异常的捕获和处理
Throwable, Errorin 和 ExceptionJava异常结构中定义有 Throwable类, Exception和Error是其派生的两个子类。
Exception表示由于网络故障、文件损坏、设备错误、用户输入非法等情况导致的异常;
Error表示ava运行时环境出现的错误,例如:JVM内存资源耗尽等。
try-catch
try{...}语句指定了一段代码,该段代码就是一次捕获并处理例外的范围
在执行过程中,该段代码可能会产生并抛出一种或几种类型的异常对象,它后面的 catch语句分别对这些异常做相应的处理
如果没有异常产生,所有的 catch代码段都被略过不执行
在 catch语句块中是对异常进行处理的代码
在 catch中声明的异常对像( catch( Someexception e))封装了异常事件发生的信息,在 catch语句块中可以使用这个对象的一些方法获取这些信息
public void testprintwriter()throws Ioexception{
Fileoutputstream fos
new Fileoutputstream("demo. txt")
Outputstreamwriter osw
new Outputstreamwriter(fos,"Utf-8"),
//创建带有自动行刷新的PW
Printwriter pw= new Printwriter(osw, true)
pw.println("大家好!")
pw.close
}
多个 catch
每个try语句块可以伴随一个或多个 catch语句,用于处理可能产生的不同类型的异常
catch捕获的异常类型由上至下的捕获异常类型的顺序应是子类到父类的
try{
...
}catch(Nullpointerexception e){
...
}catch(Runtimeexceptione)
...
}catch(Exception e){
...
}
//子类型异常在前,父类型异常在后,这样的顺序依次捕获。否则编译不通过。
finally的作用
finally语句为异常处理提供一个统一的出口,使得在控制流程转到程序其它部分以前,能够对程序的状态作统一管理
无论try所指定的程序块中是否抛出异常, finallyi所指定的代码都要被执行
通常在 finallyi语句中可以进行资源的释放工作,如关开的文件、删除临时文件等。
throw关键字
当程序发生错误而无法处理的时候,会抛出对应的异常对象,除此之外,在某些时刻,您可能会想要自行抛出异常,例如在异常处理结束后,再将异常抛出,让下层异常处理块来捕捉,若想要自行抛出异常,您可以使用" throw"关键词,并生成指定的异常对象后抛出。
例如:
throw new ArithmeticException();
程序中会声明许多方法( Method),这些方法中可能会因某些错误而引发异常,但您不希望直接在这个方法中处理这些异常,而希望调用这个它的方法来统一处理这时候您可以使用“ throws"关键词来声明这个方法将会抛出异常
例如:
public static void stringtoDate( String str)
throws ParseException{
......
}