11异常处理

基础知识

1、异常是一种Exception类型的对象(异常是一种对象

  因为异常是对象,所以你catch住的也是对象,下面程序代码中catch的参数是Exception类型的ex引用变量

try {

} catch(Exception ex) { //Exception类型的对象可以是任何它的子类的实例
    //尝试恢复
}

2、如果你的程序代码会抓住异常,那是谁把它抛出来的?

//有风险、会抛出异常的代码
public
void takeRisk() throws BadException {//必须声明它会抛出BadException if(abandonAllHope) { throw new BadException();//创建Exception对象并抛出 } } //调用该方法的程序代码 public coid crossFingers() { try { anObject.takeRisk(); } catch(BadException ae) { System.out.println("Aaargh"); ex.printStackTrace();//如果无法从异常中恢复,至少也要使用printStackTrace()来列出有用的信息 } }

举例:

public class Test {

    int age;

    public void getAge(int age) throws AgeException{//声明它会抛出AgeException
        this.age = age;
        if(age > 100) {
            throw new AgeException();//创建AgeException对象并抛出
        }
    }

    public static void main(String[] args) {
        Test t = new Test();
        t.getAge(200);//调用会抛出异常的方法
    }
}

class AgeException extends Exception {//自定义异常AgeException继承Exception
    //
}

 异常是程序运行期间出现的,区别于程序编译期间的代码错误

3、为什么编译器不管RuntimeException

  大部分RuntimeException都是因为程序逻辑问题,而不是以你所无法预测或防止的方法出现的

执行期间失败状况,你无法保证文件一直都在,你无法保证服务器不会死机,但是你可以确保程序

不会运行不合理的逻辑,例如对只有5项元素的数组取第八个元素的值。

4、try/catch块的控制流程

 5、finally:无论如何都要执行的部分

/*
如果try/catch块有return指令,finally还是会执行,
流程会条到finally然后再回到return指令
*/
try {
    turnOvenOn();
    x.bake();
    trunOvenOff();
} catch (BakingException ex) {
    ex.printStackTrace();
    trunOvenOff();
}

6、try/catch/finally/throw/throws实例:

public class Test {
    public static void main(String[] args) {
        String test = "yes";
        try {
            System.out.println("start try");
            doRisky(test);
            System.out.println("end try");
        } catch(ScaryExteption ae) {
            System.out.println("scary exception");
        } finally {
            System.out.println("finally");
        }
        System.out.println("end of main");
    }

    static void doRisky(String test) throws ScaryExteption {
        System.out.println("start risky");
        if("yes".equals(test)) {
            throw new ScaryExteption();
        }
        System.out.println("end risky");//不再执行
        return;//不再执行
    }
}

class ScaryExteption extends Exception {}//ScaryExteption为自定义异常
String test = "yes"执行结果:

String test = "no"执行结果:

7、处理多重异常

  多重方法可以抛出多个异常,但该方法的声明必须要含有全部可能的检查异常(若两个或两个异常的异常有共同的父类时,可以只声明该父类就行)

public class Laundry {
    public void doLaundry() throws PantsException, LingerieException {
        //可能抛出两个异常的程序代码
    }
}

public class Foo {
    public void () {
        Laundry laundry = new Laundry();
        try{
            laundry.doLaundry();
        } catch(PantsException pex) {
            //恢复程序代码
        } catch(LingerieException lex) {
            //恢复程序代码
        }
    }
}

8、异常也是多态的

  异常是对象,因此异常也能够以多态的方式来引用

 

9、可以用父类来处理所有的异常并不代表就应该这么做

  把异常处理程序代码写成只有一个catch块以父型的Exception来捕获

try {
    laundry.doLaundry();
} catch (Exception ex) {//恢复什么?这个会捕获所有的异常,一次你会搞不清楚哪里出错
    //解决方案......
}

  有多个catch块时要从小到大,不能把大篮子放在小篮子上面(否则会无法通过编译)

个人理解:下面例子中:当我们用父类捕获异常时(多个子类捕获效果一致)实际上在第一个异常抛出的时候就catch住了,而后程序就会执行恢复此问题的方法,程序结束。

      我们不能用父类捕获异常是因为程序运行的时候,会根据捕获的不用异常执行不同的恢复该异常的方法,如果我们用父类捕获异常,那么只能写一个

      异常的恢复方法,难以满足一个恢复方法恢复所有类型的异常

public class Test {

    int age;

    public void getAge(int age) throws Age1Exception, Age2Exception{
        this.age = age;
        if(age > 100) {
            throw new Age1Exception();
        }

        if (age > 200) {//上面抛出异常后,该if语句也不再运行
            throw new Age2Exception();
        }
    }

    public static void main(String[] args) {
        Test t = new Test();
        try {
            t.getAge(500);
        }catch (Age1Exception ae) {//只能catch住Age1Exception
            ae.printStackTrace();
        }catch (Age2Exception ae) {//不运行
            ae.printStackTrace();
        }
    }
    /*效果同上面分别catch
    public static void main(String[] args) {
        Test t = new Test();
        try {
            t.getAge(500);
        }catch (Exception ae) {
            ae.printStackTrace();
        }
    }
    */
}

class Age1Exception extends Exception {}
class Age2Exception extends Exception {}

10、不想处理异常时。可以把它duck掉来避开(交给下一个调用的方法来处理

(ducking只是在踢皮球,早晚还得有人来处理这件事,如果连main()也duck掉异常,程序可编译但是运行报错)

执行结果:

 

 

posted @ 2017-08-07 09:26  亡命鸡礼花  阅读(147)  评论(0编辑  收藏  举报