00:00
好,那么我们讲完异常处理的两种方式之后呢,我们再来看看后续的两个内容啊,这两个内容完了以后呢,整个异常呢,我们算是就结束了啊,后续的这个章节当中我们都会去使用啊异常处理的啊好,那我们来看这个零五叫手动啊抛出异常对象,这个呢,抛出呢我用的叫肉了,这个肉呢,跟我们上面讲的这个roses呢,注意不是一回事啊。好,那首先呢,我们来看第一个问题。说为什么需要手动抛出异常,注意这个异常呢,其实是一个异常的对象啊。诶什么意思呢?你看啊,咱们的前面讲的这个例子呢,都是,那在程序呢,诶咱们就这样泛泛的这样一说啊,正常的一行一行的执行的这个代码从上往下呢这块去执行,那在执行的过程当中,诶出现了某一个问题了,比如说呢,我这是一个ABC,你非要呢,把这个字符串呢,转换成是一个in啊一个int类型的,那它的它呢,肯定转化不成。这时候呢,它会自动的在这个程序当中相应的这个代码的位置呢,生成一个叫的一个对象,然后这个对象就被抛出来了。
01:06
啊,然后呢,我们第二步的话呢,针对于抛出的这个异常对象呢,咱们呢,可以考虑呢,去做这个catch的这个处理叫补货,或者说呢,你说诶出现这个对象了,说我这个方法搞不定,那我呢还可以呢,去死肉。这呢就是我们讲的异常处理的两种方式了,说现在的话呢,我们针对的什么呀,就是哎,生成异常对象的这个环节呢,说除了呢,系统自动抛之外呢,我们可能还会出现手动抛出异常对象的这个场景。哎,就是可能有同学就会说了,手动抛出异常对象,那你是不是也得处理啊,哎,这个呢是的。哎,只要你抛异常对象了,不处理这个程序就停了。所以呢,手动抛也得处理,那可能有同学就会不理解了,说呢我们呃,主要的目的呢,是为了处理这些异常了,那现在的话呢,你要不出异常,这不是挺好的事儿吗?那你干嘛还主动的让他去抛出一个异常对象,后边呢自己再去处理呢。
02:01
这不没事给自己找麻烦吗?是吧,诶其实呢,不是这样子的啊,诶我们实际情况是什么样的呢?就是这个程序啊,它在执行的时候呢,确实就会有一些不满足我们要求的一些场景,比如说呢,ABC你非要转成个数值类型的是吧,他就是转不了,那对于这种场景呢,应该说呢,程序呢,提前给我们预知到这样一些问题的,就帮我们把这些问题给。给给给给操作了,操作意思就是说你如果出现这种不合理呢,它就自动的就会抛出一个异常对象,但是还会有一些实际问题呢。我就没法给你抛了,那么这个时候呢,你就自己来了。啊,不太理解,举个例子,你比如说呢,我们现在呢,呃,有一个学生是吧,叫做student了。那么这个学生的话呢,他有一个呢ID,我要给这ID呢去赋值。这呢叫学号,那么赋值的时候呢,其实我们通常都说这ID呢,它最起码你得是个正数,你不能整个负数了啊,那一旦呢,要是我们给这个ID呢,赋值呢是一个负数。
03:01
那么此时的话呢,我说呢,哎,首先你可以说呢,不合理了,那这种不合理啊,咱们写一个输出语句呢,就感觉差点意思,那此时呢,我就可以呢,让他。抛一个异常,但这种抛异常呢,没说啊,就是在Java语言层面没说这个ID不能是负的,所以这个呢,是我们实际情况啊,有的一个要求,那你如果在实际开发当中有一些具体的要求,而这要求呢,在实际操作的时候不满足的时候呢,我们就可以自己主动的去抛出一个异常对象了。不像说呢,我们去除一个数,这个零,像这种情况话呢,这个呢,或者叫前们问。想办法,这个给给了一种方案啊,那就是我抛个异常了,那现在要是这种情况呢,那你自己来了。那这个就是我们为什么需要手动抛出异常对象的一个场景。OK,来,咱们先把这个事儿说一下啊,哎,说这个在呃,实际开发中。啊,实际开发中啊,那如果出现啊,不满足这个具体问题的。
04:05
啊,或者叫具体场景的这个情况。嗯。场景的。啊,这个代码问题啊,如果出现了不满足具体场景的这个代码问题,那我们呢,就有必要。哎,手动呢,抛出一个指定类型的啊,异常对象。啊,说的就是这样一个议题啊,这个这样的一个问题啊,那么把刚才呢,我们说的这个学生这个问题呢,咱们可以呢,给大家刻画一下啊,比如说这时候大家你看啊,我去呢,写一个例子叫做student。啊,或者这块我也写成这个吧。咱们这里边儿用的这个关键字呢,叫做关于它的一个使用的啊。好,这是我们来看,首先的话呢,我在这里边儿呢,就声明一个叫做student。那这呢是一个类了,这类呢,我们声明一个特型的一个ID啊,下边呢,我们通过一个方法啊,Public word叫register。这叫注册的意思,我们给这个ID呢,做一个赋值,这个三也叫ID了,那我们这呢,去加个判断哈,说如果呢,这个ID呢,它是大于零的满足这种场景下的话呢,我就直接呢A呢就等于ID了。
05:11
哎,否则的话。那我们就进入这个else了,就是你如果呢是小于等于零的,那这个时候怎么办呢?以前的时候呢,可能我们就会写一句话啊,说呃这个你呃输入的这个ID呢,我们就要非法了。以前可能只能这样做一下,那现在的话呢,我们就可以呢,不去写一个梳理语句了,因为这个事儿的话呢,一旦你要是梳理ID不靠谱程序呢,就不让你往下执行了,所以我们就可以呢,让他哎叫手动。哎,抛出异常类的对象。那么这个抛的话呢,我们用的就是这个死肉的关键字。注意,这个叫死肉啊。哎,那后边怎么写呢?既然呢,它是一个异常的对象,对象呢都得是new,那我们就new一下。那你有问题是我,你有你有谁呀?那这块呢,就看你想抛一个什么类型的一个异常了,如果呢,你想抛的是一个运行时异常,是不是你有一个runtime exception了。
06:03
然后这个呢,他还支持呢,写一个字符串信息,那你可以把这个信息呢,也是给他就写到这儿了。那就可以这样子。好,那我这块抛的是一个运行式异常,这个呢相当于是我们抛异常对象的一个过程,下一步呢,是不是又得考虑处理了。处理的话呢,我们说运行时异常是不是可以就不处理了。所以你看这时候我们也不用说check开啊,也不用了,诶我就这么着就行。然后呢,这个代码写完了,写完以后呢,我们在上面这个main方法当中。这呢,我来一个叫student是吧。哎,造个对象,然后拿着这一呢,咱们去调这调reist这个方法,比如这块呢,我们赋了一个值呢,叫做十,估完值以后呢,我们再去调一下它这个图的方法啊,Al加上in。叫这个图斯润是吧。好OK一下,然后呢,上面这块呢,我们再打印一下。这个一行,此时呢,我们做一个执行。嗯,这呢是一个正常的情况,这个十呢附上了,所以呢也打印了这个信息了,那接着我们再把它呢,比如说改成这个叫负十。
07:06
那此时的话呢,这个复食呢,它就会进入到这个逻辑当中,我们就抛出来这个异常对象。那这个异常对象呢,抛出以后呢,咱们也没有去处理哈,就是你也没有开始finally,也没有Rose,因为是一个运行时异常嘛,我们就不处理了,所以这个时候呢,其实在这块呢,就会出来一个异常的对象,然后这个程序呢,就终止了是吧。所以下边这块呢,这个输出这个事儿呢,就不靠谱了。这不就出来一个他这样的信息吗?这个信息里边呢,你就看到是一个runtime exception,因为我们这块造的就是个runtime except的一个对象,这个信息呢,就是它。哎,就是这个意思啊,然后呢,我们输出的这个信息哈,就是这个信息。他其实呢,就是我们那个message。那咱不是有一个那个,呃,就是异常的那个get message的一种处理方案是吧。啊就这个意思哈,就是如果呢,大家要是想处理它的话呢,运营时异常咱不说不用处理嘛,但是你说我我就想处理一下,那你就可以呢,这样踹呢,比如把它包进去。
08:03
这样,然后这块呢,我们写个开这个呢,是一个runtime exception只写个E。然后这里边呢1.prints,咱们把这句话呢,也给大家放到这吧。然后一其实这块打的效果跟我们刚才呢,不处理的时候基本上一样。所以呢,咱们不是一般都不处理嘛,是吧。OK,那么这个后边这个信息。就这里边这个他哈,他呢,就相当于是我们的这个事儿,我把它呢,比如说注释一下。我这叫一点get一个。这个message啊,其实就是我们这个构造器呢,传进来的这个数据。那现在你看我们再去做一个run的时候,它打印的呢,其实就是我们这个输入的ID非法。那就他。哎,这个稍微的了解一下其实就可以了,行这呢,我们相当于呢,是抛了一个运行时异常。哎,那么我也可以抛的,不是运营11场,我要是抛一个。
09:00
叫一个普通的exception。你看这块我写了哈,一个叫ion。那这个位置呢,我们写的信息呢,是一样的啊,诶我这块粘过来。那么这时候呢,你就得小心了啊。因为你不是一个运营时异常了,所以这种操作方式我们就得需要。处理了是吧。那你出异常了,你不得处理吗?诶,那这时候你要么拆开,要么Rose,假设呢,我们这时候不在这个方法里边呢,去拆开,那我们就得在这儿,是不是得Rose一下。哎,那我我这样吧,我怕有同学在这块有点懵啊,我这个方法呢,我先复制复制一份啊。上面这个呢,我先把它呢给删掉,这个呢我现在就不用它了,这个相当于我们抛的是一个运营式异常,下边我们去抛一个,哎,非运营式异常啊。哎,Through,那由于呢,你这块呢,Through是一个exception,所以这块我们把它呢,处理的时候呢,也得写个exception。那就得这样。
10:00
好,这样完了以后啊,回过来,那刚才那会儿呢,我们说呢,你要是一个呃,运营式异常呢,其实也就不用去处理了,但现在呢,我们不是一个运营式异常。是吧,哎,这时候呢,你可能呢,抛出来的是一个普通的exception,那此时呢,就把这个问题呢,是不是抛到没方法这了。没方法这块呢,是不是就得处理了。对,也就是说对于现在这种情况呢,你是必须要拆开吃的。这个东西扔进去啊,然后开始这块呢,就针对于你,诶上面呢,死肉过来的你是一个exception,所以这块我也就写成个exception了。啊,这个呢,还是叫1PRINT,那就这样了。行,然后具体执行的话呢,其实这个跟刚才呢差不太多哈,这边呢,输入的你返回的是exception,然后呢,输入的ID非法啊就这样。稍微的感受感受啊,这个呢,就是我们所谓的叫手动抛出异常类对象的这样的一种场景。啊好,那么回过来啊,那么大家呢,如何去理解这个手动和自动这个事儿。
11:04
那咱们呢,多去唠叨两句哈,那这块的话呢,其实也是把我们整个这一章的内容啊,想着整个呢,我们从一个角度上呢,把它串起来啊,前面呢,我们在讲异常处理第一种方式的时候呢,提到过这个事儿叫做抓抛模型,当时呢,我们讲过两个过程,不妨呢,我把这两个事儿呢,CTRLC一下咱们粘过来啊,大家去体会一下。就是通过这个角度呢,咱们把整个这一章的内容啊,我们给大家做一个小结啊,什么意思看一下。我们说整个呢,这一章我们讲的就是第一个啊,出现异常对象了,第二个呢,就处理异常,这就这个核心内容,好,那么出现异常对象呢,我们把它呢理解成叫抛。如呢,程序在执行过程当中啊,这个呃,一旦呢,出现异常了,我们呢,就会生成对应的异常类的对象,并将此对象抛出,实际上呢,现在来看这个事儿的话呢,我们这儿呢,其实就相当于是叫自动跑是吧。是这意思吧?哎,分成家自动跑。
12:01
哎,你看什么意思啊,说在执行的时候呢,你出现异常了,出现异常了,它在这个位置呢,就自动。诶,生成对应异常类的对象,并将起诉对象抛除啊,这个事儿呢,我们就暂时先不考虑了,是吧,这个都是满足的哈,这个呢就是自动的事儿,比如说你是除零了,你还是这个呃,类型转化异常了等等都会抛,那除了这种情况之外呢,我们说还可以呢,叫手动跑。也就是说这个抛的话呢,咱们分成了两种情况啊,手动抛呢,就是程序在执行的过程当中。啊,然后呢,诶不满足这个指定。哎,条件的情况下。哎,我们主动的使用这个叫死肉这个关键字。啊,四周呢,后边我们就加上了一个叫异常类的对象。哎,通过这样的这个方式啊。抛出哎,主动使用这样的这个方式。
13:02
这个抛出异常对象。哎,这呢,就是一个手动的意思了。诶这个前面呢,我们讲的都是自动抛,现在的话,我们讲这个肉的时候呢,是属于手动抛的,然后这呢属于第一个过程,那一旦抛出以后呢,这个代码就不继续向下执行了,那怎么办呢?我们得考虑去抓,抓呢,咱们这个狭义上来讲的话啊,这个抓呢,我把它呢也删掉了哈。哎,狭义上讲,那这个。抓咱们其实理解成了就是异常处理的,这个叫哎TRY了。啊,方式呢,来哎捕获一场是吧。哎,然后并处理这个处理的话呢,就在catch里边呢,你写这个比如print啊这种方式,这呢狭义上呢,其实抓抛模型,这个抓呢,其实就是catch的意思了,那我们也可以呢,把这个概念呢,给它再扩展一下啊,就是广义上讲。那咱们那就可以把这个抓的事儿呢,咱们就理解成是叫处理吧。
14:02
那如果把它理解成处理的话呢,那我们讲过异常处理的两种方式。啊,所以广义上讲呢,我们把抓。哎,把这个诶抓是吧。哎,理解为啊处理。啊理解为处理啊,则此时呢,对应着异常处理的两种方式。哎,两种方式,第一种,哎,我们叫做try catch finally。哎,那么第二种。Rose。啊,也就是说呢,这里边儿呢,其实第一种呢,诶就是狭义的理解,广义上的话呢,我们把这个呢也算进来了,所以呢,这就是产生异常对象的过程,这呢就是处理异常对象的过程。那通过这个呢,大家去理解一下谁呢,就是这个肉和肉是两个关键字,它俩的位置和作用呢,是完全不同的哈。
15:03
啊,你看他们各自是干什么作用的,要体会清楚,那他俩是竞争关系啊,还是算合作关系啊,还是算什么关系啊?诶,其实呢,算是一种合作关系是吧,一个呢是产生异常对象的过程。一个呢,是处理异常对象的过程是吧。诶,那前面呢,说了这种叫自动跑,其实啊,大家如果你要是翻看源码的话呢,你会发现呢,这里边儿所谓的自动抛啊。只不过呢,不是我们自己写的而已,是吧,你看源码的时候,其实它也是这样做的。对,也是用死肉了。啊,咱们呢,只是把这种理解成呢,是自动抛了啊这个呢,是我们自己主动的来用的。啊,再举一个例子啊,也就对应的是我们下边这个练习了,这个练习里边的第一道题啊,诶我们在前面做某道题的时候呢,其实当时就想用这个手动抛在哪呢?诶多肽诶是多肽吧,啊接口这块里边有个练习二啊,里边有个这样的一个场景。好,那咱们就找到这个位置。
16:01
那第八章。这个接口的时候。我们有一个这个练习二里边呢,有这样的几个问题啊,把这几个类呢,我就CTRLC了啊。诶,我就粘到这儿了,CTRLV。啊,这个一粘过来,大家其实一看就明白了,当初呢,我们是先写了一个接口,这个接口有个方法,这个方法呢,用来比较对象大小的啊,正的负的零啊,然后呢,我们提供了一个circle,就是这个圆,圆呢本身它不能比较大小,它的这个此类呢叫comparable circle,继承于circle的同时呢,又实现了这个接口,又具备了这样一种规范,就是比较大小了,当初呢,我们把这个方法就给重写了。重写的时候呢,你看当时这样说的啊,说他俩要一样的就是零,然后呢,诶不一样的情况下呢,看你是不是这个类型的,是这类型的话,我们先强转。呃,这块呢,这些点咱们就把这个呢,就先删了啊。关键就看这块啊,那你如果要是一个comp的话呢,我们就去比了,关键的你要不是呢,当时我们说没有办法,只能先二将就一下,那现在来看的话呢,你要不是一个compable circle,咱们就直接呢抛一个异常了。
17:05
这不就是手动抛的一个场景吗?啊,你都不是一个这个类型的,那我抛个异常是最合理的,因为呢,你返回正的负的零都不太合适。那我就抛个一场。那再演示一下啊,我现在抛的是这个叫运行时异常。这个呢,只是相当于咱们刚才看到这里边儿的第一个过程哈,你只是抛了一个对象,那我现在处理了吗。没有处理,注意,只要呢,我们出现这个异常的话,其实按说哈,都应该考虑去处理,只不过呢,咱们现在抛的是一个。对运行是异常,所以呢,我们就不管了。咱们这章呢叫异常处理,针对的是exception,再准确来讲针对的是。编译时的这些异常是吧?啊,运营时异常不管啊,所以这块呢,我们其实抛了一个运营时异常有可能会出现,但是我们并没有处理。但是你要是不是用的它的话。
18:01
那就得处理了是吧,你比如说这块我现在呢,就让他去入的是一个exception。那你就得考虑处理,要不这个程序就过不去了是吧。那怎么处理啊?诶,对,你要么roses,要么踹,开始假设这时候呢,我就想把它往上抛,是不是就用Rose了。好,我这个死助词呢,就想往这去写,写的话呢,针对你当前抛的类型,我是不是也得写exception。好,这个写完之后的话呢,诶怎么又报错了。那没有怎么着。没有在掉的时候,不是不是那个问题。哎,这块呢,对你看往哪回呢,我们现在呢,你这个方法呢,是不是实现了我们这个。Object这个接口里的。而这个结构里边的这个方法呢,咱们没有抛任何的异常。你看就是因为你看看这哈,这呢是你这个所谓的这override嘛,你的这个实现啊,但是在我们这个接口里边,你看。
19:04
它是没有抛任何异常的,所以呢,你这个所谓的实现的方法,或者叫重写方法,是不能抛给我比我更大的是吧。所以呢,要想你这块能抛怎么办?对你这块呢,去一下是吧,你得配合一下我。这个加了以后呢,我们此时呢,你再回到这块,它就没事了。这这不用管它是吧,这就没事了,这就可以了。能理解吧?所以以后呢,我们有时候会看到在一个接口的一个声明这块呢,明明是个抽样方法,怎么还加了一个抛出异常呢,就是为了配合的,在这个具体的实现的时候呢,可能会好是吧。好,那这个完了以后呢,你看下边这个报错了,是因为咱们在这块呢,这不掉它了吗。哎,这就相当于是你选的是第二种处理方案,叫做Rose,那你得负责哈,那你的调用者呢,是may may方法这块呢,调的时候你得考虑一下怎么处理了。那在这个时候呢,咱们可以呢,再使用一下这个叫才开始是吧,已经到没方法这了。
20:00
诶,把这个代码呢,CTRLX咱们扔到这儿,然后在这儿呢,写一个catch。写一个叫exception。哎,然后1.print,哎,这是不是就搞定了。那如果说你要没有出现异常,行,那就正常在这块执行,你要真出现了。开始这块处理一下。那就这样就可以了。啊,体会一下。啊,体会一下这样的一个场景,好诶拉回来,诶说白了还是这个事儿哈,在一些实际开发当中啊,我们除了满足一些自然的一些要求之外呢,如果你这个题目呢,还有一些具体的一些要求,甚至说呢,你这个两个数做除法,除法的时候呢,正常我们说呢,分母不能为零,这呢是提前系统已经帮我们考虑到了啊幺为零呢,我就抛一个算术异常,但现在假设你做这个除法的时候,你说分子和分母的要求都不能是负数。像你这种自己额外的要求,那你就如果出现负数了,你就自己主动的自己去抛了。哎,就是这样的一个场景,好,不管你是自动抛的还是手动抛的,正常来讲呢,都得考虑处理,只不过呢,我们说对于运营是异常呢,就不管了。
21:04
那编译是一场,我们再考虑处理。好,这呢注意一下两个过程。那通过这个问题的话呢,其实我们也能够说清楚了啊,大家呢,要能够去答一个问题。啊,这个问题是什么呢?就是我们这个肉和肉呢,有什么区别。啊,这要写个五的话呢,这呢是一个常见的。没人提了。这个会打吗?那他不会这么干脆是吧?这俩的话呢,其实长得真的是挺像的,而且大家用的时候呢,还真有可能整不明白啊。这个你总不能说这个是一个单三啊,非单三啊,这个形式是吧。啊。肯定不是那意思了啊,这俩的话呢,怎么说呢。嗯。其实我这块呢,写的比较清楚啊。
22:01
哎,我写的已经很清楚了,他说我怎么看不出来呢,是吧?诶这个如果呢,仅仅从这个使用形式上来看的话呢,可以这样说,诶我把这个结论呢,我说一下我就不写了啊,诶你可以说呢,这个Rose呢,从使用上来讲,它是使用在方法的声明的出是指明呢,我们是把产生的异常对象呢,继续向上一层抛出。属于异常处理的一种方式是吧。然后呢,这个肉呢,是使用在方法内部。你像我们刚才写的,这不都在内部使用的吗。哎,后边跟着的是一个异常类的对象。表示呢,叫手动的抛出一个指定异常类的对象。诶,这个呢,注意我刚才说的呢,这算是告一段落了啊,这个说的就是它使用的这种场景。一个是在声明处,一个是在方法内,后边跟的是什么?这个跟的是类型,这个跟的是对象是吧。这个呢,只是我们所谓的这个叫行哈,就是你看到的,那么你光答这个呢,还显示不出来你的这个高度。
23:02
再把它再往上拔一层,那就是他俩的使用场景啊,是完全不一样的,或者他们解决的问题是完全不一样的。一个呢,是用来产生异常对象的。一个呢?是针对你产生这个对象呢,如何去处理的是吧。所以是完全不同的。他呢是第一个环节,它是第二个环节。啊,咱们有一句话叫叫什么,就是比如说叫呃上游。排污。下游至武。这个话是吧,那么这里边儿的上游排五乌好比是异常的对象是吧,这个排是不是就是死肉。就是你把这个异常对象你给抛出来了是吧,诶创建了一个,然后抛出来了,而我们这个下游至五至就是处理。乌,就是处理你这个对象,那质呢,有两种方式,其中一种是Rose是吧?
24:01
所以这个肉呢,相当于是排roses呢,那肉相当于是排roses呢,相当于是质。去体会一下,你把这个问题要说出来了,那这个高度立马就上来了是吧,所以呢,关于它的使用呢,你不能光简单说这个格式长这样,这个后边跟着异常类型,这个呢,只是我们写的时候这个型的区别。主要的区别呢,还是用的场景呢,完全是不一样的啊好,这个问题呢,我就说清楚了。OK啊好,下面说如何实现手动抛出异常啊,就抛出异常对象,这个咱们刚才已经说过了啊,说呢在方法内部是吧,啊这个满足。哎,指定条件的。啊情况下。哎,然后呢,去使用啊,咱刚才咱们说的这个结构哈。哎,肉这个就变成加号了,哎这样一个情况。异常对象的这个方式。哎,抛出,所以这块呢,其实为啥答这个问题呢,大家不太容易说清楚呢,是因为你看我现在呢,我在好多地儿呢,都老写抛出哈,实际上这块呢,是对应到中文这块呢,也没办法了,这个词汇呢,显得有点乏力,有的时候这个抛出呢,它相当于我说的叫死肉是哈,有的时候这个抛出呢,对应的就成肉了。
25:12
就相当于中文这块我混着用了,但是在英文当中呢,这是两个单词啊。嗯,这个注意一下。下边有个主点说死肉后边的代码呢,不能被执行,编译不通过,这个呢也很好理解啊,以咱们这个学生这个例子来说。嗯,回到咱们刚才的这个,嗯。这块是吧。哎,举这个例子来说,你说这个后边呢,我们还能写输出语句吗?显然不行,是吧是吧,词语句哎,不能被执行。那因为呢,你一旦呢,要抛出异常这个就直接出去了是吧,后边这块肯定是执行不了的啊,这个呢也非常的好理解。啊,这就完事了。好,这呢,就我们说呢,叫手动抛出一个异常对象,哎,这个知识点就对应的是我们这个第五个。
我来说两句