java-深入篇-java的异常处理

来源:互联网 发布:微交易系统源码下载 编辑:程序博客网 时间:2024/06/12 20:27

或许大家都试过这样的一种经历:不管是玩手机还是电脑,在运行一个软件的时候,有时候会无端端的崩溃掉。这种情况在就连qq在早期的时候也会发生。当然,不仅是他,就连我们使用的系统,也会有这种情况。比如windows就比较喜欢弹出一个提交错误信息报告,告诉你程序哪里有问题了,要重启。你按下确定键后,他就帮你重新启动,你要是按了其他,他就直接退出了。这要是在平时倒没什么,但是如果你在玩游戏玩到刺激的时候忽然挂掉的话,那才叫心痛啊是吧。当然,没有什么程序是不会出问题的,作为开发者,我们应该做的就是尽力去避免出现bug,以免影响用户对软件的体验度。同时,一旦出现了错误,我们也应该尽快去进行修复,而基于这一原则,就诞生我们今天的主角——java的异常处理。

什么叫异常处理

java中的异常处理是基于面向对象的一种运行态错误处理机制,通过对异常信息的封装实现对用户非法操作、参数设置异常、硬件系统异常,运行时网络状态更换等在运行态中可能出现的异常信息的处理机制。

异常处理机制的体系结构

前面说到异常处理是基于面向对象而实现的,也即是说java把大部分可能存在的异常信息都封装成一个个对应的类了。当然,我们也可以在原有类的基础上进行拓展。这就涉及了异常处理机制的体系结构:
* 继承结构

  Throwable    |- Error      系统级错误    |- Exception  可修复的异常        |- 其他Exception        |- RuntimeException            |- NullPointerException            |- ArrayIndexOutOfBoundsException            |- ArithmeticException            |- NumberFormatException            |- ClassCastException            |- InputMismatchException            ...

在异常处理机制中,为了方便对异常信息进行跟踪,一般设定异常信息的内容如下:

  错误信息:        *)类型名称        *)提示消息        *)行号

案例说明:

package testabstractclass;import java.io.IOException;public class Test1 {    public static void main(String[] args) throws IOException{        int i = 1;        i = i/0;        System.out.println(i);    }}

运行该程序,报错如下:

这里写图片描述
你看,这是一个用整数去除以0时,系统报出的异常。在这里我们就可以清晰地看到这个异常是什么意思,并且该异常出现的位置都已经显示出来了,如此我们就可以直接在代码中定位到该位置并且对错误进行修改,这就是异常处理机制最大的好处:跟踪错误代码。并且,还有一个比较重要的好处,就是对于一些可修复的程序来说,我们可以直接捕获到这个异常,并且直接修改修复它,从而避免了系统崩溃的发生。同样的例子,我们进行修改如下:

package testabstractclass;import java.io.IOException;public class Test1 {    public static void main(String[] args) throws IOException{        int i = 1;        try {            i = i/0;        } catch (Exception e) {            i += 1;        }        System.out.println(i);    }}

运行结果,你会惊喜地发现,最后打印出来的是2,而不是报错。这就是因为我们在程序中捕获到了这个异常并且做出了相应的修改。那么,由我们的代码便引出了下面的一个问题:

如何捕获异常:

在java中,捕获异常的格式可以简述为下面这样:

try{可能发生异常的代码块}catch(可以捕获的异常1){处理异常1的代码}catch(可以捕获的异常2){处理异常2的代码}finally{处理完所有异常后一定会执行的代码。在这里注意的事。如果在这里没有出现异常,最终也会执行这行代码}

注意,在这里,格式是可以发生变化的,我们可以增加catch块,也可以不需要finally块。但是我们总不能说因为可以省略就可以不说吧,因此在这里便列出了一个相对完善的包含所有异常关键字的格式,它的流程如下:至于其他的格式,你们可以根据这个来参考实现:
这里写图片描述

如何处理异常的两种方式

在上面的代码中,我们实现了如何检测代码异常以及处理这个异常。但是对于一些异常来说,是难以实际去修复的,那怎么办呢?常见的一个方法是:编写一个异常处理类,当我们捕获到任何异常时,都将其进行统一的处理,比如在软件上线时,我们不可能一个一个用户说:哦,你这里出现了这个问题,我给你修复了,你用我修复的这个吧。要是这样的话,铁定会把开发者给累死啊,怎么办呢?我们就把说有用户出现的错误信息集中发到开发者的邮箱,然后开发者进行修改,测试没问题之后,就对外公布说:我们的版本升级了,更好玩哦,快来更新吧!你看,这就是为什么我们要更新的好处啦。好,下面干货走起,以android中处理错误信息为例,请看:

/** * 同一处理异常 * @author 明立 * *///Throwable是所有异常的父类,这里使用的技术就是多态了    public static void handleException(Throwable mThrowable){        StringWriter stringWriter = new StringWriter();        PrintWriter printWriter = new PrintWriter(stringWriter);        mThrowable.printStackTrace(printWriter);        String throwableinfo = stringWriter.toString();        //isRelease,版本标志符        //true:上线版本        //false:开发版本        if (isRelease) {        //将异常信息发送至服务器,由服务器发邮件给开发者        }else {        //在Log上打印错误信息        }    }}

当然,还有一种情况,即当我们还没捕获到异常的时候,程序就已经崩溃了,那怎么办,聪明的程序员老大哥们已经想好了处理办法,即重写一个类继承UncaughtExceptionHandler方法捕获异常并提示用户并在两秒后重启应用,这就避免了你崩溃后用户直接把你删掉的结局。干货如下:

/** * 程序异常crach时处理类(自动重启) * @author 明立 * */public class CrachHandler implements UncaughtExceptionHandler {    //程序的Application实现类,声明周期为应用创建到应用彻底销毁    private CApplication mApplication;    public CrachHandler(CApplication mApplication) {        super();        new Thread().start();        this.mApplication = mApplication;    }    @Override    public void uncaughtException(Thread thread, Throwable throwable) {        // 用上面的ExceptionHandle类联网发送错误信息        ExceptionHandle.handleException(throwable);    //出现自动重启        new Thread(){            public void run() {                Looper.prepare();                Toast.makeText(mApplication, "程序出错,自动重启", Toast.LENGTH_SHORT).show();                Looper.loop();            };}.start();            try {                Thread.sleep(2000);            } catch (Exception e) {                ExceptionHandle.handleException(e);            }            //两秒后自动重启软件,用peddingIntent实现            Intent intent = new Intent(mApplication,MainActivity.class);            PendingIntent pendingIntent = PendingIntent.getActivity(mApplication, 0, intent, Intent.FLAG_ACTIVITY_NEW_TASK);            AlarmManager alarmManager = (AlarmManager) mApplication.getSystemService(Context.ALARM_SERVICE);            alarmManager.set(alarmManager.RTC, System.currentTimeMillis()+2000, pendingIntent);            mApplication.exit();    }}

当然,在这里将Android可能有点超纲了,但实际未然,因为我们介绍完java深入知识点之后,就会正式接触到Android开发,而期间在各方面可能都会使用到异常,因此在此粘出来,以来让大家看看Android和Java之间的联系。二来也可以让大家提前掌握这个知识点。而如果说想要深入去理解何为异常处理机制的话,可以参见这篇博客(真的是写得非常详细,极力推荐):
java提高篇-java异常处理

下一篇:Java的多线程实现,敬请期待:
如果对文章有疑问,可在下方评论指出,共同探讨~

1 0
原创粉丝点击