通过异常处理错误
基本异常
异常情形是指阻止当前方法或作用域继续执行的问题。
异常处理程序的任务是将程序从错误状态恢复,以使程序要么换一种方式运行,要么继续远行下去
可以创建一个代表错误信息的对象,并且将它从当前环境中“抛出”,这样错误信息就传播到了更大的环境中,将此称为抛出了一个异常。
if(t=null)
throw new NullPointerException();
抛出了异常后,在当前环境中就不用再担心这个问题,它将会在别处得到处理
异常参数
用new在堆上创建异常对象
所有的标准异常类都有两个构造器:1.默认构造器 2.接受字符串作为参数,以便能把相关信息放入异常对象的构造器
throw new NullPointerException("t=null");
捕获异常
try块
如果不希望方法内部抛出异常后就结束,可以在方法内设置一个特殊的块来捕获异常,它是跟在try关键字后面的普通程序块:
try{
//也许会出现错误的代码
}
异常处理程序
抛出的异常必须在某处得到处理,这个地点就是异常处理程序,针对每个要捕获的程序,得准备相应的处理程序,通常紧跟在try块之后,已关键字catch表示:
try{
//也许会出现错误的代码
}catch(Type1 id1) {
//类型1的异常处理
}catch(Type2 id2) {
//类型2的异常处理
}
异常处理程序必须紧跟在try块之后,只有匹配的catch子句才能得到执行
终止与恢复
Java支持终止模型:一旦异常被抛出,就表明错误已无法挽回,也不能回来继续执行
创建自定义异常
要自己定义异常类,必须从已有异常类继承
class SimpleException extends Exception {}
public class InheritingException {
public void f() throws SimpleException {
System.out.println("Throw SimpleException from f()");
throw new SimpleException();
}
public static void main(String[] args) {
InheritingException sed=new InheritingException();
try {
sed.f();
} catch(SimpleException e){
System.out.println("Caught it!");
}
}
}
异常说明
在程序库不将源代码一起发布的情况下,Java提供了相应的语法(并强制使用这个语法),告知客户端程序员某个方法可能会抛出异常类型,这就是异常说明,属于方法声明的一部分,紧跟在形式参数列表之后。
代码必须与异常说明保持一致
捕获所有异常
可以只写一个异常处理程序来捕获所有类型的异常,通过捕获异常类型的基类Exception就可以做到
catch(Exception e){
System.out.println("Caught an exception");
}
使用finnally进行清理
对于一些代码,可能希望无论try块中的异常是否抛出,他们都能得到执行。为了达到这个效果,可以在异常处理程序后面加上finally子句。
class ThreeException extends Exception{}
public class FinallyWorks {
static int count=0;
public static void main(String[] args){
while(true){
try{
//Post-increment is zero first time;
if(count++==0)
throw new ThreeException();
System.out.println("NO exception");
}catch(ThreeException e){
System.out.println("ThreeException");
}finally{
System.out.println("In finally clause");
if(count==2) break;//out of while
}
}
}
}
可以得出,无论异常是否被抛出,finally子句总能被执行
finally用来做什么
当要把内存之外的资源恢复到它们初始的状态时,就要用到finally子句。
在return中使用finally
因为finally子句总是会执行的,所以在一个方法中,可以从多个点返回,并且可以保证重要的清理工作仍旧会执行。
public class MultipleReturns {
public static void f(int i){
System.out.println("Initialization that requires cleanup");
try{
System.out.println("Point 1");
if(i==1) return;
System.out.println("Point 2");
if(i==2) return;
System.out.println("Point 3");
if(i==3) return;
System.out.println("End");
return;
}finally{
System.out.println("Performing cleanup");
}
}
public static void main(String[] args){
for(int i=1;i<=4;i++)
f(i);
}
}
异常的限制
当覆盖方法的时候,只能抛出在基类方法得异常说明里列出的那些异常,这意味着:当基类的代码应用到其派生类对象的时候,一样能够工作,异常也不例外。
参考书《Java编程思想》