00:00
行了,那到此为止吧,咱们这个总算是把咱们方法的重载就算讲完了,那么接下来看看方法递归。我们来看一下法递归,各位啊,这个递归呢,还是非常有意思的啊,非常有意思,来看一下这个递归啊。嗯。递归?什么是递归?我们得先去理解一下。这个递归算法呢,其实它是有一点点小难度。啊,要理解有点小难度啊。我刚才的意思是写Java源代码的时候和调用的。源代码。不在。一个文件夹中及生成的class不在同一个文件中,这样可以吗?不行。不行啊,东不行啊,不行,这种方式不行,这种方式到后期你我教你之后才行,你现在2CLASS文件还得放到一个文件夹里边,两个class文件还得放到一个文件夹,后期就明白了啊。行吧,咱看一看方法递归啊。
01:02
方法递归的话,我就单独在这儿建个文件夹吧,啊就叫做。方法递归呗,啊递归啊,不是递归啊,是递归来方法的递归啊,这是个什么东西。来看一下。你叫S啊零一。各位看一下啊,我们来看一下学学这个递归啊,学完这个递归之后呢,整个这个就结束了啊,再往下呢,就是关于我们的哎,名扬对象了啊明对象来看一下。什么是方法递归?什么是方法递归,我来演示一下,好吧,演示一下啊,Public class。啊,叫做reccusion啊,递归reccusion啊呃,然后TEST01,然后public static void man。
02:10
啊,然后接下来呢,我在这里呢,Main方法去调一个some do some方法啊,这个do some方法在哪啊,我在这定义出来啊,Public avoid avoid do some啊然后接下来我们在这呢,哎。有这么一个方法啊,输出一下system.out.print打印输出说do some method execute就行了啊,非常之简单的一个程序啊,这是一个普通的类,这是一个程序的入口,对不对,这是一个主方法啊,然后接下来我们在程序执行过程中,我们调了do sum,那么调了我们的do some方法之后呢,我们do some方法怎么着啊,哎,在这里。输出一个数据啊,啊,输出这个这个结果。那么接下来呢,我们在这里呢,去编译并且运行来Java CCD啊,我们叫方法是不是,哎,递归进去一下啊,看一看有一个文件啊,我们叫reccus,是不是来接下来我们叫做Java c,编译什么呢?我们的reccus.java,文件编译之后我们去运行reccu,然后把后边class去掉,回车do some方法执行,那么也就是do some这个方法执行是不是?哎,现在这个程序呢,没有任何问题啊,没有任何问题可以正常执行,那大家思考一个问题啊,如果说我这个位置改成叫do some begin,完事之后呢,我在system system.out点打输出什么呢?我就要do some什么呀,Over,哎,然后接下来我们再去编译,再去运行,没什么问题吧,编译再运行,大家看是不是就do some begin do some,就do some方法开始执行,Do some方法执行结束,好,那么没有任何问题,接下来在这个开始和结束之间,我去调用什么呢?哎。
03:52
方法,我问大家do some是不是一个方法?Do some是个方法,那我问大家,既然是方法,能不能调用?
04:02
Do some既然是一个方法,那么do some方法可以调用吗?当然可以,对不对?哎,当然可以,那么这个时候呢,我们就去调一下我们这个do some方法。那有同学就很,就感觉很诡异,说老师方法去调do some do some,开始执行do some,执行过程中又去调了do some方法这个东西有意思啊。这是怎么走的呀?哎,各位方法自身去调用,方法自身,这就叫方法递归啊,这就叫方法递归,注意啊,方法自己调用自己。自己调用自己啊,就是方法递归啊,方法递归。那么大家想一想,这个程序会出什么问题啊?思考一下这个这个程序会出什么问题。来各自讨论一下啊,各自讨论一下。我给大家一分钟时间啊。或者两分钟时间吧,啊,你想一想好不好,嗯。
05:01
好了,那大家呢,说的非常有道理啊,非常有道理,这个呢,看来大家这个水平啊,都还是不错啊,都还是不错,那么之前呢,我曾经讲过一个方法呀,它这个从上往下呀,执行它是逐行执行的,那如果是这行代码它不结束呢,下边这行代码是永远都执行,执行不到的,对不对?哎,那么这块咱们这个程序是怎么回事呢?就是说我们去问方法,去调用我们的do some方法对不对,哎,Do some方法,然后接下来怎么着呢?我们do some方法呢,开始执行,执行这一行之后呢,紧接着我们去调用这个do sum方法,那么调用这个do some方法的时候呢,就相当于又重新开始执行这个do sum方法。对不对,就是这行代码是不结束,下边这是不会执行啊。就这行代码就是永远执行不到啊。这行代码永远执行不到,我说什么是递归啊,各位我说一下啊,是这样的。这样啊,我们复制复制一下行不行,哎,复制一下啊,复制一下哎。
06:00
来复制一下啊来来头晕吗?好复制完了啊,往后呢,我再来几个省略号啊,啥意思啊,你看好了,就相当于说呀,我这个闷方法去调这个do some方法,Do some方法呢,怎么着呢?哎,执行这个之后呢,去调do some,哎这个do some,诶你就可以想象成是这个do some。你明白吗?就是调这个do sum方法的时候,哎,这个do sum方法进来开始执行,这个只有说你这个代码执行结束了,这个第16行才算结束,才能进行第18行的代码,我不知道大家理解不理解。理解不理解这句话啊,就是说当然Java中不我是故意这么写的啊,Java中是不允许这个方法重名的,你看这方法名字都一样了,对不对,哎,不允许重名,但是我现在我只是打个比喻啊,打个比喻希望各位能够理解一下什么意思,就是说你看啊,我这个do some是不是调执行这个就执行完这个是不是调这个do some,这个do some能不能看成是这个do some。这个do some是不是就去执行这个do some去了。哎,这个代码片段在方法区里边存啊,但你每调一次这个方法,它就会给这个方法分配什么。
07:03
空间是不是每调一次这个方法就会给这个方法分配什么,哎,内存空间。叫什么压战吧?哎,那么调这个方法就开始执行这个大框里的代码,那如果你这个大框里的代码执行不结束的话,我第16行就结束不了。什么时候才算我第16行结束呢?哎,我调了你do sum方法,这个do sum方法从中上给执行结束了,我的do sum方法这行第16行才算结束啊,所以说do sum调了这个do some之后,那么这个输入do some begin,输入do some begin之后又去调这个do some,这个do some呢?哎,他没他调这个do some,其实就相当于调这个do some。啊,然后接下来这个怎么着。他没有结束,那第二十五行是不是代表不结束啊。对不对,第二十五行不结束,那就这边执行呗,这边执行这个调do some,这个do some方法可不可以看成是这个do some方法,这个do some去调的这个do sum。然后这个do萨开始执行,执行执行到这儿呗。是不是,那这个do some,是不是又去调这个do some去了。
08:01
是不是do some begin一直输出?哎,一直输出,一直输出,哎,假如说突然有一天啊,突然有一天怎么着呢,执行到这个读some方法的时候,突然啊。我这个去掉啊,假设啊,假设突然有一天啊,有一天一个条件。成立了。啊,这个do some结束了,你能想到就如果个条件么?啊,成立了对吧,那现在这return,诶,终于他不需要再重复这件事情。那么这个时候如果你想想是不是这个do some去调了,去执行这个之后去调了这个do some,而这个do some方法是不是就调了这个do some,但是do some方法在有一天某个条件成立了,诶return结束之后,我们这个代码是不是就结束了,这个代码如果结束的话,我问大家是不是就相当于第六十五行结束了,第六十五行如果结束了,这个是不是就输出了,输出之后这个是不是就结束了,这个结束之后我问大家是不是当于这行代码结束了,这行代码结束这个是不是就输出了,输出之后这个代码是不是就结束了,这个代码结束之后,那我问你是不是就相当于这行代码结结束了。
09:12
哎,这个整体就结束,因为这个结束之后马上它嘛输出嘛,是不是这个结束之后呢,紧接着这个就结束,这个结束之后输出它,然后紧接着怎么这个结束,哎,这个结束,然后你来这个结束了,这个终于结束之后呢,这个就输出它了,输出它之后怎么着,哎,这个就结束了,这个结束之后怎么着,哎,这行代码终于结束了,然后输出这个do some over,接下来整个方法结束之后,哎,这个do some总算第十行结束了,第十行结束之后呢,往下一结束,诶问方法结束了,程序就退出了,是这样一个一个原理啊,我这么说,大家理解理解。理解不理就是这,这就叫递归,什么叫递归?就是方法自己调用自己,自己调用自己,这就叫递归。啊,但是大家看看我这个递归是不是没有结束条件。我这是假设有一天一个条件成立了,这个do some结束了,对吧?哎,结束了,但大家看看我这个do,萨姆们去调我do some是不是就没有头啊?
10:07
有能有能结束的时候吗?没有结束的时候是不是?没有结束的时候,那是不是就一直压占啊好占内存,占内存是不是一共一共也就那么多。占内存。各位。我天哪理解。各位do some啊,调这个do some do some又掉do some do some,调的是这个do some,这个do some掉do some do some掉这个do some一直完掉掉掉掉掉掉掉掉掉,一直掉一直掉,哎,我们这个程序现在是没有结束条件的。那么没有结束条件,就是现在这个递归啊,是没有结束条件的啊,目前这个递归是没有结束条件的啊,会出现什么问题。啊,会出现什么问题,那么接下来我们把内存图画一下,内存图画一下各位啊。
11:04
认真听啊,认真听,认真去听,然后才能够听懂啊,要不然你听不懂我在讲什么东西啊。先不要去讨论啊,先不要去讨论,来,我们先分析一下个。哎,想象成什么呢?我们的一个Java虚拟机gbm,然后呢,接下来呢,我们在这块呢,还是老规矩,就是我们的方法区是不是,哎方法区内存方面的啊方法区,然后呢,接下来呢,我们在这块呢,哎,咱们叫什么呀,叫堆内存。对啊。堆内存。对应内存啊,然后紧接着呢,我们这块仍然是,哎,我就想想我们的站呗,对吧,Sta是不是占啊。占stack占内存,那么这块呢,是没的没的。
12:03
那么在我们这个首先啊,会进行一个类的加载,会把我们这个类呢,加载到我们的这个程序当中,也就是说我们的代码片段啊,代码片段诶这块。有一个代码片段啊。就加载到我们的方法区里边了,方法区里边哎,就是代码。点啊代码片段啊,在这里code的啊,Code我就不再不再画了啊,不再画了,那加载进来之后,首先第一个就先去执行闷方法,那么之后闷方法执行它就会压站,那么这个其实就是闷方法。就是闷方法各位啊,这个就是那个焖方法方法啊战争。啊,闷方法最先调用,那么这个闷方法当中去调了哪个方法,大家看去调了这个杜萨。他去调这个do some方法呀,哎方法一旦调用怎么着啊,他就压站是不是,哎我昨天我说过了要调do some。这个do方法呢,它一旦执行到这里之后啊,它就会停下来。
13:03
停下来啊,它不再往下往下走了,不再往走了啊,它掉这个do sum姆方法就会导致什么do萨姆方法压站。明白吧,哎这个位置呢,其实就是do some方法的战争,就是do some,哎方法战争啊,那do some方法战争这块呢,它。是怎么有的呢?哎,就是因为在这个位置上我们怎么着啊,哎,掉了这个do sum方法,所以是不是把这个压进来了。对吧,哎,把这个押进来了啊各位啊,那么我们把这个押呀。来把它压进来之后呢,接下来这个代码就闷方法就卡到这儿不动了,明白吧,闷方法就因为闷方法不再占顶部了,现在在这个站的顶部的方法是do some方法,Do some方法在暂停处于活跃状态,这个处于暂停状态,它停在这不动,那么这个时候do some方法呀,它就开始执行它输出第一个叫do some begin。Do some begin输出了,那输出这个do some begin之后呢,大家看。
14:01
啊,输出do some begin之后呢,接下来大家看是不是紧接着我们这个程序就调了do some方法是不是好,那我问你,一旦他在这里调了这个do some方法,是不是就意味着我们又要压战了,对不对,哎,又压战了。因为它方法调用啊,所以这个时候呢,哎,它就会怎么着,停在这一行,停在这一行啊,它不会继续往下走了啊,因为它调这个方法,这个方法就涉及到一个压战的问题,所以这个时候又压过来一个方法叫什么叫do some啊do some方法战争,哎,这个地方又来了,叫do some方法战争啊,又压进来,那压进来之后呢,哎,就相当于什么呀,哎,这个位置怎么着啊,就压进来了呗。是不是,哎这个位置给压进来的啊,压进来之后呢,我们还是那句话啊,它这个程序啊,它就不会再继续往下走了啊,那么这个do some方法调的话,那do some方法大家都知道这个方法是不是先输出这个是不是,哎,所以这一块同样一个道理,哎,它会先输出谁呀,叫do some来begin,然后紧接着呢,哎,它会去调谁啊?哎,Do some方法是不是,那do some方法调用呢,就相当于在这块,哎又来一个do some,那你又来个do some呢?妥了,那这块怎么办呀?哎,它就相当于怎么着啊,哎又在这怎么着卡住了。
15:14
因为你调用方法,它就会给这个方法分配空间,那分配空间就会压占,所以这个时候呢,又压过来一个对不对,哎,这个地方我们调查来叫做哎,Do some方法战针是吧,那压过来是怎么回事,就是从这压过来的。好了,哎呀,偏了啊。那偏了好了。那么这块同样一个道理,大家想想是不是这个do some方法开始执行,会先输出一个do some什么begin吧,哎,那么这个时候在这儿是不是会输出do some begin,是不是,哎,Do some begin来颜色改一下,然后呢,接下来它还会继续往下调,调谁呢?调do some。对吧,哎,会计网调调度上了。啊调度那这块呢,其实怎么着啊,哎又给它什么?哎停下来了,停下来了,停下来之后怎么着啊,哎继续往下压,哎往下压对不对,哎压过来,那我这块呢,我就不再接接着往下画了,各位啊,大家理解这个意思就行了,哎就一直往下压,一直往下一直往压压压压。
16:19
哎,那么大家想一想,是不是我们控制台会一直输出,它什么意思,这个会输出。对吧,这个会输出do some begin一直输出。是不是,哎,但是大家注意占的内存是不是有限。占内存是有限的啊,占内存有限。也有不够不够用的时候,也有不够用的时候。啊也有不够用的时候,所以最终啊会导致什么呀,占的内存溢出。最终啊,会导致占内存溢出。
17:05
啊,这是因为一直压榨。从来没有。谈战。从来没有谈战啊,你不是说突然有一天,诶好消息啊,这个方法从这怎么着执行结束了,这个一旦执行结束,诶这个代码是不是就结束了,就往下走了,对不对,这个往下走,这个是不就弹出去了,然后呢,哎漏出来他之后呢,他这边是不是就往下走了,哎往下走之后呢,这个执行结束,这个弹出去,哎这个是不是就露出来了,往下走是不是就结束了。对吧,但是对不起,这会儿呢,他并没有说,并没有说结束。因为我们这个程序目前也是递归嘛,方法自己去调用自己是不是哎就导致了一个问题,什么问题,就是哎一直压占,从没谈占啊占内存最后溢出了啊占内存溢出了,好了这块呢,我们保存一下啊保存一下放到document下来递归原理。
18:00
就递归啊,递归没有结束条件的时候,会发生占内存溢出错误。啊,站内统计出,我们一起来看一下是不是这样的Java c呢,我们去编译一下Java,我们去运行。你看出问题了,看见了吧,刷刷刷刷刷刷刷,一直一直刷一直刷,你看。最后出问题了,这这是这是问题啊,这是问题,你看这个站还能顶一会儿,你看你发现我站是不是可以顶一会儿啊,那顶的时间还不短,你看走走走走走走走走走走走走走走走走走走走走。哎呀,我想我想逮住这个啊,想逮住这个世界,我不好逮啊。哎,能不能逮住啊,我看一下吧,我看一下吧。诶,逮逮住了吗。逮住没逮住?这上面信息显示显示不全,显示不全,对不住。
19:02
我想逮住这个信息也不容易啊。逮住了吗?好像有点意思。哎,有点意思,好,大家看啊,Exception in thread men在闷方当中出了异常说呀,Java language sta overflow。这个单词。咱们。打开。我们的。百度我们搜一下好吧,啊,其实这个呢,你翻译其实也能翻译过来。啊叫做占的内存溢出错误。嗯。有在线翻译吗?对战花园。
20:05
叫堆栈溢出错误啊,堆栈溢出错误。其实就是溢出错误。站一出错误,各位啊。站一出错误。他为什么会占溢出错误啊,那就是因为什么呀?哎,因为我们这个递归没有结束条件,各位啊。第二点,当归。程序没有结束条件。一定会发生什么。占内存溢出错误,Stack overflow。Overflow啊。占内存溢出错误,所以递归必须要有结束条件。
21:00
啊,这是一个非常重要的知识点,啊,这是一个非常重要的知识点。各位啊,非常重要的一支线就是递归必须要结束条件,没有结束条件肯定是不行的啊。
我来说两句