Carregando...

Recursão em Java

Escreva um método chamado down que receba um int chamado n. Se n for 0 ou menos, pare com um return; vazio. Senão imprima n e depois chame down(n - 1) a partir do mesmo método. Em main chame down(3);. O ecrã deve mostrar três linhas: 3, depois 2, depois 1. O método chama-se a si próprio com um número menor até a paragem terminar a cadeia. Essa autochamada com paragem é o que esta página ensina.

Um método que se chama a si próprio

Na página de escopo, mark corria uma vez e terminava. Aqui down corre e depois inicia outro down com um argumento novo antes de a primeira chamada acabar de todo. Cada chamada tem o seu próprio n. A cadeia só termina quando uma chamada encontra a paragem.
Crie um ficheiro de programa pequeno chamado Ladder.java. O public class da primeira linha deve coincidir com o nome do ficheiro: public class Ladder. Não deixe um nome de classe antigo Gate ou Sign neste ficheiro; o compilador espera que o nome da classe e o do ficheiro coincidam.
Fora de main, ainda dentro das chavetas da classe, escreva static void down(int n). Nesta página mantenha void: cada passo imprime e nada precisa de voltar com um return tipado. A paragem usa return; sem valor — só termina esta chamada. Guarde o ficheiro antes de compilar. O primeiro programa completo está na caixa seguinte.

Ladder.java com down

Esta é a versão que você compila primeiro. main tem uma chamada. down tem a paragem, a impressão e a autochamada.

down prints then calls itself

java
public class Ladder {
    public static void main(String[] args) {
        down(3);
    }

    static void down(int n) {
        if (n <= 0) {
            return;
        }
        System.out.println(n);
        down(n - 1);
    }
}

Na pasta que guarda Ladder.java, execute javac Ladder.java. Quando parênteses, chavetas e ponto e vírgula coincidem, javac não escreve uma linha própria. Depois execute java Ladder — não java Ladder.java. Tire a terminação .java do segundo comando. Os mesmos dois comandos funcionam no Windows e no macOS. O programa deve imprimir três linhas e parar: 3, depois 2, depois 1. Não deve pedir que você digite. Se o terminal esperar entrada do teclado, ainda há uma chamada nextLine de um exercício antigo. Apague-a e mantenha down(3); mais o método down acima.
Percorra a execução uma vez por ordem. Java começa em main. A chamada down(3) entra com n igual a 3. É maior que 0, por isso o método imprime 3 e depois chama down(2). A segunda chamada imprime 2 e chama down(1). A terceira imprime 1 e chama down(0). A chamada com 0 encontra n <= 0 e regressa sem imprimir. A cadeia termina. O ecrã guarda as três linhas impressas.
Cada uma dessas chamadas é uma passagem separada pelo mesmo texto do método. A primeira passagem ainda tem trabalho depois de iniciar down(2) — terminar quando a chamada interior regressar. Você não escreve quatro nomes de método diferentes. Escreve um método e deixa o argumento menor levar o progresso até à paragem.
Se mudar o início para down(2);, o ecrã deve mostrar 2 depois 1. O corpo do método fica igual; só o primeiro argumento muda, por isso a cadeia é mais curta. Começar com down(4); deve mostrar quatro linhas: 4, 3, 2, 1. Outra vez o corpo não muda; só main escolhe o primeiro valor.

Coloque a paragem primeiro

A paragem deve ser verificada antes da impressão e antes da autochamada. Se imprimir primeiro e nunca testar n, ou se chamar sempre down(n) com o mesmo valor, o programa não termina. Mantenha o bloco if (n <= 0) no topo do método nesta forma de principiante.

stop checked before print

java
public class Ladder {
    public static void main(String[] args) {
        down(2);
    }

    static void down(int n) {
        if (n <= 0) {
            return;
        }
        System.out.println(n);
        down(n - 1);
    }
}

Compile e execute de novo: javac Ladder.java, depois java Ladder. O ecrã mostra 2 depois 1. A paragem continua a terminar a cadeia quando n chega a 0. Escrever down(n) em vez de down(n - 1) envia o mesmo número repetidamente. Então o programa pode correr até o sistema o parar. O argumento menor faz parte da ideia: cada chamada deve avançar para a paragem.
Pense na paragem como a porta de saída. A impressão é o trabalho deste passo. A autochamada é o passo seguinte. Sem porta, cada passo abre outro sem fim. Se o passo seguinte usa o mesmo n, nunca caminha para a porta. Os dois erros parecem diferentes no código, mas ambos se recusam a terminar limpo nesta forma de principiante.

Cadeia de chamadas ao lado do ecrã

Leia uma chamada inicial ao lado das linhas que produz. Cada linha é uma visita a down que ainda imprime.

📊 down call chain for down(3)

Chamada Valor de n Linha no ecrã
primeira down(3) 3 3
depois down(2) 2 2
depois down(1) 1 1
depois down(0) 0 (sem linha — paragem)

Um erro comum é omitir a paragem. Então cada chamada imprime e chama de novo sem fim. Outro erro é imprimir depois da chamada recursiva em vez de antes. Nesta página a impressão vem primeiro, por isso o ecrã conta para baixo. Se mover println para baixo de down(n - 1), a ordem das linhas muda — mantenha a impressão acima da autochamada para a contagem decrescente daqui.
O escopo da página anterior ainda importa um pouco: o n de cada chamada é o parâmetro dessa chamada. O n da chamada exterior não se reescreve quando a interior corre. A interior tem um n separado. Quando a interior regressa, a exterior continua depois da autochamada — e nesta página isso é simplesmente o fim do método.
Uma demo restante de Gate com mark(4) pode ficar no mesmo ficheiro e confundir o ecrã se main ainda chamar mark. Limpe main até down(3); ou down(2); enquanto aprende esta página. Não aninhe down dentro das chavetas de main. Os métodos ficam dentro da classe, ao lado de main.
Escrever System.out.println("down"); em main imprime a palavra down. Não inicia a cadeia. Mantenha down(3); quando quiser as três linhas da contagem decrescente.

Mais uma forma: a paragem não imprime nada

Já viu que a chamada com 0 regressa em silêncio. Também pode praticar com o valor inicial 1. O ecrã deve mostrar uma só linha: 1. Depois a chamada seguinte é down(0), que para.

down starting at one

java
public class Ladder {
    public static void main(String[] args) {
        down(1);
    }

    static void down(int n) {
        if (n <= 0) {
            return;
        }
        System.out.println(n);
        down(n - 1);
    }
}

Depois de javac Ladder.java e java Ladder, o ecrã mostra uma linha: 1. O mesmo corpo cobre down(3), down(2) e down(1). Só o primeiro argumento em main muda. Isso basta para esta página de principiante. Ideias mais profundas como devolver uma soma a partir da recursão ficam para cursos posteriores; aqui o objetivo é a autochamada, o argumento menor e a paragem.
Se o ecrã não mostrar nada, verifique se main ainda chama outra coisa, ou se o teste de paragem está errado — por exemplo if (n >= 0) pararia antes de qualquer impressão ao começar com um n positivo. Mantenha n <= 0 como saída silenciosa e um início positivo em main para aparecer pelo menos uma linha.

Antes de classes

Você pode escrever down(int n), parar quando n for 0 ou menos, imprimir n e depois chamar down(n - 1). Em main, uma chamada inicia toda a cadeia. O ecrã mostra as linhas da contagem decrescente. Um método que nunca avança para a paragem não termina. A página seguinte é classes; aí começa a construir tipos com campos para além destas páginas de métodos static.

🧠 Teste Seu Conhecimento

Pronto para Começar

Teste Seu Conhecimento

Desafie-se com este questionário interativo e veja o quão bem você entende o tópico

❓
5
Perguntas
🎯
70%
Para Passar
♾️
∞
Tempo
🔄
∞
Tentativas

📝 Instruções

  • Leia cada pergunta cuidadosamente
  • Selecione a melhor resposta para cada pergunta
  • Você pode refazer o quiz quantas vezes quiser
  • Seu progresso será mostrado no topo