JAVA第十四弹(异常处理二)

来源:互联网 发布:加入中国籍难吗 知乎 编辑:程序博客网 时间:2024/05/17 20:23

----------------------android培训、java培训、期待与您交流! ----------------------

                                                       JAVA第十四弹(异常处理二)

                    ——————(个人见解,有错误的地方欢迎批评指正)—————

                                                             (如有雷同纯属巧合)

在我们调试程序中,经常会遇到多重方法调用,异常可能发生某个方法中,这时候想要知道异常发生的根源就可以使用异常对象自动收集的堆栈追踪来获取相关的信息。

看看下例就是最简单的堆栈追踪:

public class StackTrack {public static String A(){String str = null;return str.toUpperCase();}public static void B(){A();}public static void C(){B();}public static void main(String[] args) {try{C();}catch(NullPointerException ex){ex.printStackTrace();}}}


运行程序后如下:

堆栈追踪信息中显示了异常类型,接下来就是异常的根源在代码的第6行,然后是各方法的调用,从这些信息中很清楚的看到异常的发生源和发生位置。printStackTrace()还可以接受PrintStreamPrintWriter的版本,可以将堆栈追踪信息以指定的方式输出到别的地方(例如文档)。

要善用异常追踪,在使用throw重抛异常是,异常的追踪堆栈起点仍然是异常的发生根源,而不是重抛异常的地方,还是上面的例子,假如上述例子中方法内部只能处理一部分的异常,还需要使用该方法的客户端根据运行环境进行其它的处理,那么假如这么写:

public class StackTrack {public static String A(){String str = null;return str.toUpperCase();}public static void B(){A();}public static void C(){try{B();}catch(NullPointerException ex){ex.printStackTrace();throw ex;}}public static void main(String[] args) {try{C();}catch(NullPointerException ex){ex.printStackTrace();}}}


上述中,程序运行结果如下:

看上面的结果两个异常堆栈信息都是一样,如果想要让异常堆栈起点为重抛异常的地方,可以使用fillInStzckTrace()方法,这个方法会重新装填异常堆栈,将起点设为重抛异常的地方,并返回Throwable()对象。改进上面的代码,如下:

public class StackTrack {public static String A(){String str = null;return str.toUpperCase();}public static void B(){A();}public static void C(){try{B();}catch(NullPointerException ex){ex.printStackTrace();Throwable t = ex.fillInStackTrace();throw (NullPointerException)t;}}public static void main(String[] args) {try{C();}catch(NullPointerException ex){ex.printStackTrace();}}}


再看看这次的运行结果:

异常是程序中非预期的错误,异常处理是在错误发生时采取的措施。有些时候,需求或设计时就可以确认程序在某些情况下一定处理什么状态或一定不处于某个状态,假如不是则是个严重的错误。这时候可以用JAVA提供的“断言”机制。断言的结果一定是成立或不成立,预期结果与实际程序状态相同时,断言成立,否则断言不成立。断言有两种格式:

       assert booble_exprssion;

       assert booble_exprssion : detail_expression

booble_exprssion若为true则什么也不发生,假如为false则会抛出java.lang.AssertionError异常,假若使用第二种语法,假如booble_exprssion false则会将detail_expression显示出来,如果当中是个对象,则会调用toString()显示文字描述的结果。AssertionError继承自Error属于严重的异常,假如抛出AssertionError异常,程序应该终止。看看下例:

class AssertDemo{public void show(int num){if(num > 0){System.out.println("合法值");}else{System.out.println("非法值");}assert num>0 :"请检查参数";System.out.println("继续流程!");}}


因为assert关键字是在JDK1.4之后才加入的关键字,为了保证1.4之前使用assert作为变量导致的冲突问题,默认执行是不启动断言检查的,假如要在执行时启用断言检查,可以在执行java指令时,指定-enableassertions或者-ea自变量启动断言检查。看看测试类:

public class AssertText{public static void main(String[] args) {AssertDemo assertDemo = new AssertDemo();assertDemo.show(-1);}}


程序输出结果为:

assert作为判定程序的某个执行点必然或者不是某个状态,它不能用为代替if或者其他判断语句使用,也不应当作为程序执行流程的一部分。

程序中因为错误而抛出异常时,原本执行的流程就会中断,抛出异常的代码后面的代码将不会被执行,如果程序开启了相关系统资源,使用完毕后就必须要考虑关闭资源。但是要是抛出异常后,是否能正确关闭资源就是个问题了。JAVA提供了finally{……}语块,不管程序是否有异常finally都会被执行。

try{String str = null;str.toUpperCase();}catch(NullPointerException ex){System.out.println("空指针异常");}finally{System.out.println("关闭资源");}


上述程序输出结果是:

空指针异常

关闭资源

如果撰写的程序先return了而且也有finally区块,那么finally区块会先执行完后,再将值返回。

public class Main{public static int show(boolean bool){try{if(bool){return 1;}}finally{System.out.println("finally被执行!");}return 0;}public static void main(String[] args) {System.out.println(show(true));}}


上述程序输出结果为:

finally被执行!

1

在我们开发和维护程序过程中会出现各种各样的异常,一个好的异常处理方式能很大程度的提高开发和维护的效率,看看下例:

     try{

             //代码块

      }catch(SomeException ex){

            //空的,什么都没有

      }

这样的代码会给维护带来严重的后果,因为异常信息会完全终止,之后调用此程序代码的客户端完全不知道发生了什么事,造成除错非常困难,甚至找不到出错的根源。还有一种错误的处理异常的方式,就是对异常做了不适当的处理,或者显示了不正确的异常信息,例如,有时由于某个异常层级下引发的异常类型很多:

    try{

        //代码块

    }

    catch(FileNotFoundException ex){

        //做些处理

    }

    catch(EOFException ex){

        //做些处理

    }

有些人为了省麻烦,或者因为经常处理找不到文档的错误,写成这样:

    try{

       //代码块

    }

    catch(IOException ex){

        System.out.println(找不到文档);

    }

在别人使用程序时,真的发生了EOFException异常或者是IOException的子类型异常,但是错误的异常信息会一直显示找不到文档,因而误导了除错的方向。所以,在我们开发程序中,应当慎重撰写异常的处理方式。

 

----------------------android培训、java培训、期待与您交流! ----------------------

 

原创粉丝点击