引发StackOverflowError的Java递归程序四类技术疑问咨询
Java递归程序疑问解答
1. 为何返回类型为double时,BlueJ编译器未在返回方法时显示语法错误?
因为methodTest()方法的返回类型本身就是double,你返回的methodTest()调用结果属于double类型,完全符合方法的返回值要求,所以语法上是合法的。编译器只会检查类型匹配,不会管递归是否会无限执行(无限递归会导致运行时栈溢出,但不属于语法错误)。
2. 如何在使用和不使用递增变量的情况下终止该程序的递归调用?
使用递增变量的实现方式
首先要确保终止条件的代码能被执行到,避免出现“unreachable statement”错误。核心是在递归调用前加入条件判断,当满足终止条件时返回固定值:
public class methodTest { private static int callCount = 0; public static double methodTest() { callCount++; System.out.println("qwerty"); // 终止条件:调用次数达到3次时停止递归 if (callCount >= 3) { return 0.0; } System.out.println(methodTest()); return methodTest(); } }
你之前报错是因为把终止分支的代码写在了无限递归的语句之后,导致编译器判定该代码永远无法被执行,所以要把条件判断放在递归调用之前。
不使用递增变量的实现方式
可以通过传递参数控制递归深度,修改方法签名增加参数,同时提供无参入口方法:
public class methodTest { // 带参数的核心递归方法 public static double methodTest(int depth) { System.out.println("qwerty"); // 终止条件:深度为0时返回 if (depth <= 0) { return 0.0; } System.out.println(methodTest(depth - 1)); return methodTest(depth - 1); } // 无参入口,设定初始递归深度 public static double methodTest() { return methodTest(3); } }
每次递归调用时将深度减1,直到满足终止条件。
3. 计算机执行System.out.println(methodTest.methodTest())语句时会进行哪些操作?
执行这条语句时,流程如下:
- 触发静态方法
methodTest.methodTest()的调用,进入方法执行:- 执行
System.out.println("qwerty"),打印字符串"qwerty"; - 创建
methodTest类的一个实例对象(该对象后续未被使用,属于冗余代码); - 再次执行
System.out.println(methodTest.methodTest()),触发新的递归调用,重复上述步骤;
- 执行
- 当某个递归调用触发终止条件并返回
double值时,当前层级的System.out.println会打印这个返回值; - 打印完成后,继续执行当前方法的
return methodTest()语句,再次触发新的递归调用。
4. 为何将System.out.println(methodTest.methodTest())中的.methodTest替换为.obj1时,编译器会提示“cannot find symbol - variable obj1”的语法错误?
obj1是methodTest()方法内部定义的局部变量,它的作用域仅限于当前方法的执行上下文,只能在方法内部直接使用。而methodTest.obj1是试图通过类名访问一个静态成员,但你的类中并没有定义名为obj1的静态变量,所以编译器找不到这个符号,从而报错。如果要通过类名访问,需要把obj1定义为类的静态成员变量。
内容的提问来源于stack exchange,提问作者Super Coder
相关产品推荐
相关产品推荐

