一、什么是异常
异常就是说啊,你走路,走着走着,鞋底掉了,这就是异常。
这个呢,是一种意料之外的情况,说白了,没有人会知道鞋底会掉,所以,我们需要将这种超出我们管控的东西,管理起来,并称它为异常。
二、Java中异常的定义
Java中的异常可能产生于程序员没有预料到的各种情况,比如说在操作文件的时候,打开流之后,发现文件不存在,但是程序又在执行着,Java不会给你去处理这种不存在的情况,所以就直接报错,告诉你代码运行过程中存在问题。就像这样:
你看,告诉你有问题,然后程序就停止运行了。
三、异常的种类
Java中,异常的种类十分多,当然,我们不需要死记硬背,见的多了,你就记住了。
这个是我从百度图上面找到的,虽然种类不是很全,到处是......,但是我们学习起来是足够了。
我们从左面先看,Throwable,这个是所有的异常的“爹”,可以说所有的异常的父类都是这个。
然后这个Throwable父类下面有俩子类,一个是Error,一个是Exception,下面我们来说一下这俩子类。
Error——错误。这个呢,是程序无法处理的错误,表示运行应用程序中较严重问题。比如说OutOfMemoryError这个错误,这个是指内存溢出的错误,你说内存溢出我们程序员该怎么管控?而且大部分的Error是没有办法通过程序去管控的,所以我们可以不太去关注它,我们主要来学习Throwable的另外一个子类,Exception。
Exception——异常。这个才是我们要说的异常,上面的Error叫错误!
这个东西呢,我们可以通过程序来解决,所以我们主要来学习它。异常我们也分为两种,一种叫做运行时异常,一种是受检查异常。
运行时的异常,我们只有通过程序跑起来了,才知道有没有错误,就像读取一个txt文本一样,不运行,你怎么知道会出现异常?
受检查异常,就是在我们编写代码的时候,Java会提示需要我们来处理这个错误,还用这个读取txt来说,我们上代码。
(提前透露一下:操作文件需要有流,这个我们后面会讲的,先看异常。)
看报错了,但是这个错不是说我写错了,我们移动上去看一下是什么错误。
Java中提示我们说是找不到文件的异常需要我们处理,只有我们处理了,才可以运行,不然编译都过不去。
四、如何处理异常
通过上面的例子,我们可以看到,异常啊是一定要处理的,不然有的连编译都过不去。
我们这时候来说一下如何去处理异常,这里呢,有两种方法,一种是捕获异常,一种是抛出异常。
捕获异常:
在Java中,是使用try{ 可能要出现异常的地方 } catch (异常类型 a){ 捕获并处置try抛出的异常类型 a }
这是我们常见的一种捕获异常的方式,除去上面那种样子,我们还会见到一种样子
try{ 可能要出现异常的地方 } catch (异常类型 a){ 捕获并处置try抛出的异常类型 a } finally { 无论是否发生异常,都将执行的语句块 }
我们用这种方式来捕获一下我们上面那个图中的异常。
然后我们运行一下这段代码。
是不是就捕获住异常,并且呢,执行完成。我们来看一下这段输出的内容。
首先是画圈的地方:FileNotFoundException 这个大家可以自己翻译一下,就是文件找不到异常,并且后面提示给你,具体找那个文件找不到,并且我们看最下方的引起错误的地方是我们的代码14行那句话,这个也没有错,因为就是在实例化流的时候,找不到文件。
用了这种方式之后,我们再来看带有finally的,继续上代码:
我们现在在14行这个异常语句下面再加上一句输出,我们看能不能输出。
???并没有输出,原因呢,是因为上一句代码已经发现异常,并且被捕捉到了,那么之后的代码就不会再去运行了。所以这个输出执行中的语句并没有被执行,如果我们非要让它输出,我们可以这样写
这时候就用到了我们的finally关键字
我们再运行:
是不是就可以了,这也跟我们给出的定义也是一样的,不管这个异常有没有,我们都会输出。
当然,如果我们再写代码的过程中,try代码块(我在这下一章去说这个代码块)中有多种异常怎么办?我们呢可以这样去写
可以多个catch,去做捕获,但是,我们一般为了方便,只写一个catch,异常呢,我们写的就是Exception,因为啊,Exception是所有的这些个异常的爹或爷爷或祖爷,所以我们可以这样写:
它可以识别到具体的异常去。但我们作为初学者,尽量不要这样,等你熟系了异常体系之后再这样去写。
抛出异常:
抛出异常呢是说,当前操作的这个类不去处理异常,而是交给到调用它的类去处理异常。
我们在抛出异常的时候会使用到Java的一个关键字 throws 。下面我们来写例子。还是刚刚内个例子吧。
我们改写成这样的,然后呢,我们在有异常的类方法中加入关键字 throws ,并且给定一个异常
或者,直接鼠标移动上去
选择这个。
问题又来了,选那个?如果我们对异常不熟悉,我们尽量选择下面的,这里呢,我们选择Exception就好,有的会问了,为啥不去选择这个Throwable?很简单,Throwable包含了Error和Exception,这个程序里面很明显不会引起Error,所以我们就选择Exception就好。但是我这里选择这个IOException,选择这个是为了另一个知识点。
这时候我们发现
上面的调用类又出错了,这是因为throws关键字,它在fileTest中不做异常的处理,而是转交给调用它的类去做了,所以,我们需要将调用它的类也抛出异常 或者捕获异常,这里我们选择继续抛出。
发现没有,变成三个了?原因是这样的,因为我们被调用类fileTest()抛出的异常是IOException,所以,调用他的类就不能抛出IOException的子类了,只能是和fileTest()方法一样的或者在它之上的类。
我们选择一个Exception,然后运行。
抛出异常,然后呢,程序停止运行,大家好也没有输出出来。执行完成也没有输出出来。这就是抛出异常,遇到异常立马抛出,下面不管写了什么代码,一概不运行,直接上抛。
这就是两种异常的处理方式。
五、throw关键字
看清楚啊,throw 和 throws ,这是俩关键词啊,上面我们用的是带有s的,接下来我们介绍的是没有s的。
throw 这个也是表示为抛出异常,不过抛出的方式不一样。我们来上代码:
还是上面的那个例子,我们不在主程序中做抛出了,而是做捕获。
运行,发现可以输出大家好。现在呢,我们来说一下这个throw 的用法。
我们如果将catch中的e.printStackTrace(); 注释掉,程序会输出成什么样子呢?
我们可以看到,就一个大家好了。
我们如果自己定义一个错误,比如说就定义一个出错了。怎么弄呢?我们就可以用throw来去做。
是不是很OK,可以自定义异常,这就是Java提供给我们的一个便利的地方。但实际上自定义不是这么来操作的,我们后面会说到这个的。这个主要是体验一下throw关键字。
先来这么多大家先看的