难度
初级
学习时间
30分钟
适合人群
零基础
开发语言
Java
开发环境
- JDK v11
- IntelliJ IDEA v2018.3
提示
本教学属于系列教学,内容具有连贯性,本章使用到的内容之前教学中都有详细讲解。
1.如何处理异常呢?
在回答这个问题之前,我们先来看一段程序。
该程序上一章已经演示过了,它会出现一个叫做“java.lang.ArithmeticException”的异常,然后程序会停止。
本章,我们的任务是处理掉这个异常,并且让程序顺利执行完毕,不会因为异常而停止。
在处理异常这个问题上,Java也给我们提供了办法。
接下来,来看看。
2.捕获异常
处理异常先要捕获异常,因为只有你捕获到这个异常,你才可以去处理这个异常,比如上面的算术异常“java.lang.ArithmeticException”,你得先捕获它,然后再对它进行处理。
如何捕获异常呢?
将可能引发异常的代码用try-catch代码块括起来。至于try-catch代码块详细是什么,我们一步一步来解释。这里大家先看格式:
看来起,好像很复杂的样子,其实不然,很简单。
我们来跟随着例子一步一步来解释try-catch是什么,以及有什么用。
演示:
请在Main类main()方法中制造一个异常。
请使用try-catch代码块来处理这个异常。
请观察程序运行结果。
代码:
Main类:
结果:
错误信息:
文字版:
java.lang.ArithmeticException: / by zero
at main.Main.main(Main.java:13)
从运行结果来看,虽然我们使用了try-catch异常处理机制,但是我们的异常好像并没有得到多大的解决。
各位,这个是程序正常打印出来的错误,和上一章中程序遇到异常停止运行并打印错误性质是不一样的。不信?那我们就来改改catch代码块里面的代码:
运行程序,执行结果:
各位,请看,结果是不是不一样了?这个异常就这样被我们用一句输出语句就处理了。
而且,我们在trt-catch代码块下面再写一行代码,它也能被执行到:
运行程序,执行结果:
从运行结果来看,符合我们预期所说的异常被处理以后,程序正常往下执行。
好了,我们还是回到之前的程序。
我们来分析一下程序代码。首先是看try-catch里面的代码。
try里存放的是有可能发生异常的代码块:
如上图中的第13行和第15行代码,你觉得它们有可能发生异常,那么请使用try将其包裹起来。
catch负责捕获异常:
当你将有问题的代码用try包裹起来后,假如真发生了异常,怎么办呢?接着要使用catch来捕获这个异常。
3.为什么要捕获异常?
因为如果你不捕获异常,该异常就会被Java虚拟机抛出(异常要么被捕获,要么被抛出),当Java虚拟机抛出异常时,系统也不知道该怎么处理这个异常,它就只能停止你的程序。但是如果你捕获该异常,那么就可以在catch里面处理该异常,你自己想怎么处理就怎么处理,而且程序还不会被停止。
4.catch语句里面的参数类型
我们看到上图中的catch代码块里面有一个参数,这个参数的类型是Throwable类类型。
Throwable类是什么?
Throwable类是Java语言中所有错误和异常的父类。只有作为此类(或其子类之一)的实例的对象才被Java虚拟机抛出,或者可以被Java throw语句抛出。类似地,只有这个类或其子类之一可以是catch子句中的参数类型。(暂时不理解没有关系,后面还会讲到Throwable)
因为Throwable的子类包括有Error类和Exception类,所以catch子句中可以书写Exception。
Exception是一个普通的Java异常类,它是所有异常类的父类。
异常类上一章我们了解到,就是将可能发生的程序错误用类来描述,这样的类我们称之为异常类。
到现在,我们已经把try和catch了解了一下,try里面包裹的是可能引发的异常,catch负责捕获在try代码块中可能引发的异常。
5.try-catch捕获更精确的异常
什么叫捕获更精确的异常呢?
你比如说,1除以0,这是一个算术异常,也就是ArithmeticException。你捕获的时候,可以在catch子句中写ArithmeticException参数类型,你还可以使用ArithmeticException的父类Exception作为catch子句的参数类型。
使用Exception作为catch参数类型有什么问题吗?
当然有问题了,就好比我捕获了一个动物,请问大家我说清楚了吗?没有,我怎么知道你捕获了一个什么动物,一只狗?还是一只猫?表达不清楚。同理,我说我捕获了一个异常,请问我捕获了一个什么异常?大家知道吗?不知道,我只写一个Exception在catch子句中,大家根本不知道我捕获的是啥异常,所以请大家以后尽量把异常写精确点。例如,算术异常ArithmeticException。我一写ArithmeticException,大家一目了然,知道是算术异常。写个Exception在哪,鬼知道是什么异常。异常一定要写具体。
我们再来通过一个示例来演示一下。
演示:
请在Main类中的main()方法里书写一段引发数组下标越界异常的代码。
请使用try-catch捕获异常。
代码:
Main类:
结果:
错误信息:
文字版:
Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: Index 4 out of bounds for length 3
at main.Main.main(Main.java:14)
从运行结果来看,我们的程序发生了ArrayIndexOutOfBoundsException异常,也就是数组下标越界异常。
接下来,我们需要对有问题的代码进行try-catch处理:
运行程序,执行结果:
从运行结果来看,程序引发的异常已经被我们解决了。
回过头来,我们来看看程序代码:
很重要的是,catch子句里面的参数类型不再是Exception,而且更加精确的ArrayIndexOutOfBoundsException。这点已经是质的提升,希望大家能够每次处理异常时,能捕获更精确的异常。
总结
- try里存放的是有可能发生异常的代码块。
- catch负责捕获异常。
- Throwable类是Java语言中所有错误和异常的父类。只有作为此类(或其子类之一)的实例的对象才被Java虚拟机抛出,或者可以被Java throw语句抛出。类似地,只有这个类或其子类之一可以是catch子句中的参数类型。
- Exception是一个普通的Java异常类,它是所有异常类的父类。
至此,Java中处理异常相关内容讲解先告一段落,更多内容请持续关注。
答疑
如果大家有问题或想了解更多前沿技术,请在下方留言或评论,我会为大家解答。
上一章
下一章
“全栈2019”Java异常第三章:try代码块作用域详解
学习小组
加入同步学习小组,共同交流与进步。
- 方式一:关注头条号Gorhaf,私信“Java学习小组”。
- 方式二:关注公众号Gorhaf,回复“Java学习小组”。
全栈工程师学习计划
关注我们,加入“全栈工程师学习计划”。
版权声明
原创不易,未经允许不得转载!