为什么这不是一个无限的递归循环?
public static void main(String[] args) {
System.out.println(isSuch(99) + " " + isSuch(100));
}
public static boolean isSuch(int n)
{
System.out.println("n is currently at "+ n);
return n > 2 && !isSuch(n - 2);
}
答案 0 :(得分:5)
它不是一个无限的递归循环,因为它最终会停止。它会停止,因为&&
运算符是短路运算符。 JLS, Section 15.23描述了&&
运算符:
条件和操作员&&就像& (§15.22.2),但仅在其左侧操作数的值为真时才计算其右侧操作数。
当递归达到n
不大于2
的级别时,&&
运算符会立即返回false
,而不会评估右手边,这是递归调用。这有效地使n
不大于2
基本情况。然后,先前的递归调用使用!
运算符将其反转,返回true
。这两个调用都会返回true
,而true
会打印两次。
值得注意的是,虽然这是一个非常深的递归,但堆栈大小足以处理这个问题。但是没有必要成为StackOverflowError
发生的无限递归循环。它所需要的只是足够的进行。致电isSuch(99999)
足以在我的信箱上生成StackOverflowError
。
此外,如果您使用了非短路运算符&
而不是&&
,那么它将是一个无限递归循环,并且无论什么是StackOverflowError
都会发生号码最初传递给isSuch
。
答案 1 :(得分:0)
短路逻辑运算符
OR 运算符在第一个操作数为true时结果为true,no 重要的是第二个操作数是什么。 AND 运算符导致 第一个操作数为false时为false,无论第二个操作数是什么 是。如果你使用 || 和&&,,Java将无法评估 右手操作数的结果可以由左边确定 单独操作。
在示例代码中,当n的值等于2时,条件
**n > 2 && !isSuch(n - 2)**
会立即变为false,因为第一个操作数为false,因此不会对下一个操作数进行求值,因此不会调用isSuch()方法。