У меня проблема со следующим кодом:
public class Recursividad1 {
public static void main(String[] args) {
System.out.println("El factorial es: "+NumeroEntero.getFactorial(5));
System.out.println("El factorial es: "+NumeroEntero.getPotencia(5, 2));
}
}
и это класс, в котором есть рекурсивные методы:
public class NumeroEntero {
private static int devuelveFactorial(int numero) {
if (numero == 0) {
return 1;
} else {
return numero * devuelveFactorial(numero--);
}
}
private static int devuelvePotencia(int valor, int potencia) {
if (potencia == 0) {
return 1;
} else {
return valor * devuelvePotencia(valor,potencia--);
}
}
public static int getPotencia(int valor2, int potencia2){
return devuelvePotencia(valor2, potencia2);
}
public static int getFactorial(int numero2){
return devuelveFactorial(numero2);
}
}
Что такое стек?
Стек в java — это стек, в котором хранятся данные, относящиеся к выполнению методов (внутренние переменные и другие).
Что такое StackOverflow?
Каждый раз, когда вы вызываете метод, в стеке выделяется память. Принимая во внимание, что память конечна, всегда есть вероятность, что эта память в конечном итоге будет заполнена.
Когда эта память заполнена, и вы делаете еще один вызов другого нового метода, JRE не может сохранить необходимые данные в памяти, потому что она заполнена, и именно тогда запускается StackOverflow.
Почему это происходит при рекурсивных вызовах?
Из предыдущего пункта вы, возможно, поняли, что теоретически вызвать StackOverflow довольно просто. Хорошая часть заключается в том, что в java есть много оптимизаций, как на стороне сборщика мусора, так и на стороне компилятора, чтобы избежать подобных вещей.
Однако один момент, когда этого нельзя избежать, - это рекурсивные вызовы:
Обычно это не проблема, потому что между методами обычно не бывает очень длинной очереди вызовов, но при бесконечном рекурсивном вызове стек быстро заполняется.
Вот почему очень важно оставить возврат, который все ближе и ближе к тривиальному случаю, который в вашем упражнении равен
numero == 0
.В чем твоя ошибка?
Ваша ошибка возникает в этой строке:
Уловить невооруженным глазом не так-то просто. Проблема в том, что, делая это,
numero--
вы применяете пост-декремент . То есть java сначала выполнит return, а после возврата результата уменьшит значениеnumero
, но уже слишком поздно .Исправить это так же просто, как изменить постдекремент на a
numero - 1
: