方法互相递归调用存在哪些弊端?对比while循环实现方案
递归替代while循环实现交互逻辑的弊端分析
问题描述
我在完成编程练习时,用递归调用的方式实现循环逻辑:exe() 根据用户选择调用 rectangleFunc 或 triangleFunc,这两个方法执行完后又会调用 exe(),直到用户选择退出。而老师的参考答案用的是 while 循环实现相同逻辑。我想知道这种递归实现有没有弊端,比如资源层面的问题。
声明:我知道代码存在一些不良实践(混合语言、调用方式),请勿对此指正。
核心弊端分析
栈溢出风险:Java线程的栈空间是有限的(默认通常为几MB)。每次递归调用都会在栈中生成新的栈帧,用来保存方法的局部变量、返回地址等信息。如果用户反复进行操作(比如连续输入几百上千次),栈会被不断压入栈帧,最终触发
StackOverflowError导致程序直接崩溃。而while循环属于迭代逻辑,整个过程仅使用一个栈帧,完全不存在栈溢出的风险。额外性能开销:递归调用需要频繁创建、销毁栈帧,还要处理上下文的保存与恢复,相比
while循环的迭代执行,会产生额外的性能损耗。虽然单次调用的开销极小,但当操作次数较多时,累积的性能差异会变得明显。潜在资源管理问题:你的代码中每次调用
exe()都会创建新的Scanner实例并关闭,递归场景下会导致输入流被多次关闭,后续的输入操作可能出现异常。不过这属于你提到的不良实践范畴,这里仅做补充说明。
涉及代码
package cui; import java.util.Scanner; import domein.*; public class VormApplicatie { int iterations; int legalRectangles; int legalTriangles; public static void main(String[] args) { new VormApplicatie().beginProcess(); } private void beginProcess() { iterations = 0; legalRectangles = 0; legalTriangles = 0; System.out.println("Rechthoeken en driehoeken\n-------------------------"); exe(); } private void exe() { Scanner input = new Scanner(System.in); int choice; do { System.out.printf("0: quit\n1: rectangle\n2: triangle\nPlease input choice:"); choice = input.nextInt(); }while(choice < 0 && choice > 2); switch(choice) { case 0 -> finishProcess(); case 1 -> rectangleFunc(input); case 2 -> triangleFunc(input); default -> {System.out.println("Unexpected error occured."); finishProcess();} } input.close(); } private void rectangleFunc(Scanner input) { int length, width; System.out.print("Please input length: "); length = input.nextInt(); System.out.print("Please input width: "); width = input.nextInt(); iterations++; Rechthoek localRect = new Rechthoek(length, width); legalRectangles += localRect.berekenOppervlakte() > 50 ? 1 : 0; exe(); /*int choice = makeChoiceToContinue(input); switch(choice) { case 0 -> System.out.println("Process stopped."); case 1 -> finishProcess(); case 2 -> exe(); }*/ } private void triangleFunc(Scanner input) { int first,second,third; System.out.print("Please input length of first side: "); first = input.nextInt(); System.out.print("Please input length of second side: "); second = input.nextInt(); System.out.print("Please input length of third side: "); third = input.nextInt(); iterations++; Driehoek localTri = new Driehoek(first, third, second); legalTriangles += localTri.isRechthoekig() == true ? 1 : 0; exe(); /* int choice = makeChoiceToContinue(input); switch(choice) { case 0 -> System.out.println("Process stopped."); case 1 -> finishProcess(); case 2 -> exe(); }*/ } private void finishProcess() { System.out.printf( "Overzicht vormen:\n\n" + "Totaal aantal vormen: %d\n\n" + "Aantal rechthoeken met opp > 50: %d\n\n" + "Aantal rechthoekige driehoeken: %d", iterations, legalRectangles, legalTriangles); } /*private int makeChoiceToContinue(Scanner input) { int choice; do { System.out.print("Do you want to stop(0) or continue(1)?\nInput corresponding number: "); choice = input.nextInt(); }while(choice != 0 && choice != 1 && choice != 2); return choice; }*/ }
内容的提问来源于stack exchange,提问作者BigFan's Ultimate Thunder
相关产品推荐
相关产品推荐

