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

或许大家都试过这样的一种经历:不管是玩手机还是电脑,在运行一个软件的时候,有时候会无端端的崩溃掉。这种情况在就连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的多线程实现,敬请期待:
如果对文章有疑问,可在下方评论指出,共同探讨~

已标记关键词 清除标记
©️2020 CSDN 皮肤主题: Age of Ai 设计师:meimeiellie 返回首页