栈
提到方法的递归调用,需要先说一下栈的存储概念。
栈是一个先进后出的压入(push)和弹出(pop)式数据存储结构。若想获取到栈底的对象,就必须先将这个对象上面的所有的对象全部从栈中移除,否则无法获取栈底的对象。
我们来看看程序中栈是如何工作的,当一个方法(调用者)调用另一个方法(被调用者)时,将会将调用者的参数和返回值一起压入到栈中,此时调用者方法处于栈顶的位置,当调用者执行到调用方法的语句时,此时调用者方法将不会继续执行,即将执行被调用者方法,那么被调用者就会与参数返回值一起压入到栈中,此时被调用者处于栈顶的位置,所以此时先执行被调用者方法。直到被调用者方法执行结束,所有的参数以及局部变量会随着方法的执行结束一起弹出栈空间,此时被调用者方法的返回值将会被带出方法,数据不会随着方法的出栈而消失,而是会落入到此时栈顶的方法中,所以方法的返回值是返回到方法的调用处
下图是以上代码执行过程中,栈空间中存储的变化:
方法的递归调用
递归调用是一种特殊的嵌套调用,是某个方法直接或间接的调用自己,实际上相当于是循环执行功能代码。换句话说,就是可以使用方法递归调用完成的功能,同样也可以使用循环完成。
方法递归调用的分类
直接递归:现有fun方法,在fun方法中调用fun方法,这种调用方式称为直接递归调用。
间接递归:现有fun1方法和fun2方法,在fun1方法中调用fun2方法,在fun2方法中调用fun1方法,实际并没有在fun1方法中直接调用自己,而是调用了fun2方法,间接的调用了fun1方法,这种调用方式称为间接递归调用。
递归调用的案例
案例:设计一个方法,使用循环计算一个整数的阶乘结果。
当然,这个案例也可以使用方法的递归调用来完成,关于这个问题使用递归调用完成时,与数学中的一类题目类似:
上图的数学问题,若想计算解集的话,需要将x的值带入到表达式中,但是对于x的不同取值范围,需要使用不同的表达式计算结果。对于这个数学问题的计算过程,再次我们就不在演示。
若使用递归调用的方法计算一个整数的阶乘结果时,我们已知n的阶乘计算方法是从1开始乘一直乘到n为止,所以1的阶乘结果是1。那么计算n的阶乘,当n>1时,n的阶乘等于n乘n-1的阶乘;当n=1时,n的阶乘等于1。通过分析,请我们可以使用分支结果完成分析过程中的:当...则...,当...则...
我们可以将递归调用写成一下格式的分段函数:
递归调用中的返回值
由于方法的返回值返回到方法的调用处,所以方法递归调用返回时是一层一层的向外返回。
我们都玩过欢乐球,欢乐球中灌了水,再将欢乐球放进一个盛水的小玻璃缸中,小玻璃缸放进一个大玻璃缸中,将欢乐球中捅破时,欢乐球中的水一定是进入到小玻璃缸中,而不是直接进入大玻璃缸中。
下图是递归调用计算阶乘的返回值的图,返回值一定是一层一层向外返回,而不是最内层的返回整个方法结束。
方法压栈与方法递归
以上叙述我们说过,一个方法在执行时,会压入栈中,而递归调用相当于多次调用同一个方法,那么递归几次,就会在栈中开辟几个相同大小的空间,所以使用递归调用时,比较好性能,我们可以通过循环来完成递归完成的功能。
以上就是动力节点java培训机构的小编针对“Java基础学习:java方法的递归讲解”的内容进行的回答,希望对大家有所帮助,如有疑问,请在线咨询,有专业老师随时为你服务。
你适合学Java吗?4大专业测评方法
代码逻辑 吸收能力 技术学习能力 综合素质
先测评确定适合在学习