Java Métodos

Um método é um pedaço de código com nome. Você escreve as instruções uma vez, dá um nome a elas e, depois, sempre que precisar, chama esse nome. É a primeira ferramenta para organizar um programa: em vez de um main enorme, vários blocos pequenos, cada um fazendo uma coisa.

Você vai aprender
  • O que é um método e por que ele existe (a ideia da receita).
  • Como declarar um método: static void saudar() { … }, parte por parte.
  • Como chamar um método e em que ordem o Java executa as linhas.
  • Por que, por enquanto, todo método leva static.
  • Como dividir um programa em métodos, e os erros do javac mais comuns ao fazer isso.

Você já usou vários métodos sem perceber: System.out.println(…) é um método, Math.sqrt(…) é outro, texto.length() também. Todos foram escritos por alguém e ganharam um nome. Nesta aula você aprende a escrever os seus. Os exemplos rodam na máquina da Ana, com o JDK 25.


A ideia antes do código: uma receita

Pense numa receita de bolo escrita num caderno. A receita tem um nome ("Bolo de cenoura") e uma lista de passos. Quando a Ana quer um bolo, ela não reescreve os passos: ela abre o caderno na página "Bolo de cenoura" e segue o que está lá. Se amanhã quiser outro bolo, segue a mesma receita de novo.

Um método é exatamente isso:

Na cozinhaNo Java
Escrever a receita no cadernoDeclarar o método (dar nome e escrever as instruções)
O nome da receitaO nome do método, como saudar
Os passos da receitaO corpo do método, entre { }
"Hoje vou fazer o bolo de cenoura"Chamar o método: saudar();

Escrever a receita não faz bolo nenhum. Só quando alguém segue a receita o bolo aparece. No Java é igual: declarar um método não executa nada; ele só roda quando é chamado.

Método ou função?

Em outras linguagens (Python, JavaScript, C) você vai ouvir "função". Em Java, todo bloco de código com nome fica dentro de uma classe e se chama método (do inglês method, "modo de fazer"). Na prática, é a mesma ideia: um pedaço de código com nome que você pode chamar.


O problema: código repetido

A Ana dá aulas e quer imprimir o boletim de dois alunos. Cada boletim começa com um cabeçalho de três linhas. Sem métodos, o programa fica assim:

public class Main {
    public static void main(String[] args) {
        System.out.println("==============================");
        System.out.println("  Escola da Ana - Boletim");
        System.out.println("==============================");
        System.out.println("Aluno: Bruno   Nota: 8.5");
        System.out.println("==============================");
        System.out.println("  Escola da Ana - Boletim");
        System.out.println("==============================");
        System.out.println("Aluna: Carla   Nota: 9.0");
    }
}
$ javac Main.java && java Main
==============================
  Escola da Ana - Boletim
==============================
Aluno: Bruno   Nota: 8.5
==============================
  Escola da Ana - Boletim
==============================
Aluna: Carla   Nota: 9.0

Funciona, mas as três linhas do cabeçalho estão escritas duas vezes. Se a escola mudar de nome, a Ana precisa lembrar de corrigir em todos os lugares. Com 30 alunos, seriam 30 cópias. É aqui que entra o método.


Seu primeiro método

A Ana coloca as três linhas do cabeçalho num método chamado mostrarCabecalho e, no main, chama esse nome no lugar de cada cópia:

public class Main {
    static void mostrarCabecalho() {
        System.out.println("==============================");
        System.out.println("  Escola da Ana - Boletim");
        System.out.println("==============================");
    }

    public static void main(String[] args) {
        mostrarCabecalho();
        System.out.println("Aluno: Bruno   Nota: 8.5");
        mostrarCabecalho();
        System.out.println("Aluna: Carla   Nota: 9.0");
    }
}
$ javac Main.java && java Main
==============================
  Escola da Ana - Boletim
==============================
Aluno: Bruno   Nota: 8.5
==============================
  Escola da Ana - Boletim
==============================
Aluna: Carla   Nota: 9.0

A saída é idêntica à anterior. O que mudou foi o código: o cabeçalho está escrito uma vez só. Para mudar o nome da escola, basta editar uma linha.

Anatomia da declaração

Vamos olhar a primeira linha do método, palavra por palavra:

static
"Estático", "da classe". Diz que o método pertence à classe Main e pode ser chamado direto pelo main. Explicação logo abaixo, em Por que static?
void
"Vazio": o método não devolve nenhum valor, só faz alguma coisa (aqui, imprimir). Métodos que devolvem um resultado são o assunto de Valores de Retorno.
mostrarCabecalho
O nome do método, escolhido por você. Por convenção, começa com letra minúscula, é um verbo e junta as palavras com maiúsculas no meio (camelCase): mostrarCabecalho, calcularMedia.
( )
Os parênteses obrigatórios. Aqui estão vazios: o método não recebe nenhuma informação. Quando ele precisar receber dados (um nome, uma nota), eles vão aqui dentro; é a aula de Parâmetros.
{ … }
O corpo: as instruções que rodam a cada chamada. Podem ser quantas linhas você quiser.

E a chamada, dentro do main:

mostrarCabecalho
O nome do método que você quer executar, escrito igualzinho à declaração (maiúsculas e minúsculas contam).
( )
Os parênteses dizem "execute agora". Sem eles, o Java não entende que é uma chamada.
;
Toda chamada é uma instrução e termina com ponto e vírgula, como o System.out.println(…);.
Onde fica o método

O método fica dentro da classe (entre as chaves de public class Main { … }) e fora do main. O próprio main é um método: aquele que o Java chama sozinho quando o programa começa. Os seus métodos ficam ao lado dele, como irmãos, nunca dentro dele.

Missão: crie um método mostrarRodape() que imprima Fim do boletim e chame-o no final do main. Use o mostrarCabecalho como modelo.

public class Main {
    static void mostrarCabecalho() {
        System.out.println("==============================");
        System.out.println("  Escola da Ana - Boletim");
        System.out.println("==============================");
    }

    public static void main(String[] args) {
        mostrarCabecalho();
        System.out.println("Aluno: Bruno   Nota: 8.5");
    }
}
public class Main {
    static void mostrarCabecalho() {
        System.out.println("==============================");
        System.out.println("  Escola da Ana - Boletim");
        System.out.println("==============================");
    }

    static void mostrarRodape() {
        System.out.println("Fim do boletim");
    }

    public static void main(String[] args) {
        mostrarCabecalho();
        System.out.println("Aluno: Bruno   Nota: 8.5");
        mostrarRodape();
    }
}

A ordem em que as linhas rodam

O programa sempre começa pelo main, de cima para baixo. Quando o Java encontra uma chamada, ele pula para dentro do método, executa o corpo inteiro e volta para a linha seguinte do main. Os números neste exemplo mostram a ordem:

public class Main {
    public static void main(String[] args) {
        System.out.println("1. O main começou");
        saudar();
        System.out.println("3. Voltei para o main");
        saudar();
        System.out.println("5. O main terminou");
    }

    static void saudar() {
        System.out.println("   Olá! Eu sou o método saudar.");
    }
}
$ javac Main.java && java Main
1. O main começou
   Olá! Eu sou o método saudar.     « passo 2: a primeira chamada
3. Voltei para o main
   Olá! Eu sou o método saudar.     « passo 4: a segunda chamada
5. O main terminou
PassoOnde o Java estáO que acontece
1main, linha 3Imprime "1. O main começou".
2main, linha 4 → saudarEncontra saudar();, pula para o método e imprime a saudação. O método acabou: volta.
3main, linha 5Continua de onde parou: imprime "3. Voltei para o main".
4main, linha 6 → saudarPula de novo para o método. A mesma receita, seguida outra vez.
5main, linha 7Imprime a última linha. O main acaba e o programa termina.

Repare também que, desta vez, o método saudar foi escrito depois do main, e funcionou. Em Java, a ordem dos métodos dentro da classe não importa: o compilador lê a classe inteira antes. Escolha a ordem que deixe o código mais fácil de ler (muita gente põe o main no topo, outros no fim).


Um método pode chamar outro

Métodos não são chamados só pelo main. Qualquer método pode chamar outro. A Ana organizou o dia da sua loja de frutas assim:

public class Main {
    static void abrirLoja() {
        System.out.println("Loja da Ana: aberta!");
    }

    static void mostrarFrutas() {
        System.out.println("Hoje temos: maçã, banana, uva");
    }

    static void fecharLoja() {
        System.out.println("Loja da Ana: fechada. Até amanhã!");
    }

    static void diaDeTrabalho() {
        abrirLoja();
        mostrarFrutas();
        fecharLoja();
    }

    public static void main(String[] args) {
        diaDeTrabalho();
    }
}
$ javac Main.java && java Main
Loja da Ana: aberta!
Hoje temos: maçã, banana, uva
Loja da Ana: fechada. Até amanhã!

O main chama diaDeTrabalho, que chama os outros três, um de cada vez. Cada método volta para quem o chamou quando termina. Ler o main agora é como ler um índice: "faça o dia de trabalho". Quem quiser os detalhes abre o método.

E se um método chamar a si mesmo?

Isso existe e tem nome: recursão. É uma técnica poderosa, mas exige cuidado para não virar uma repetição sem fim. Ela tem uma aula só para ela: Recursão.


Por que static?

Você deve estar se perguntando por que todo método desta aula começa com static. A resposta curta: porque o main é static, e um método static só consegue chamar diretamente outros métodos static.

A resposta um pouco mais longa: em Java, existem dois tipos de método.

  • Métodos static ("da classe"): pertencem à classe e podem ser usados sem criar nada antes. O main é assim, porque o Java precisa chamá-lo logo no início, quando ainda não existe nada.
  • Métodos sem static ("de objeto"): pertencem a um objeto, uma "coisa" criada a partir da classe. Para usá-los, primeiro você cria o objeto. Isso começa em O que é POO e aparece em detalhes em Métodos de Objeto.

Enquanto você não aprende objetos, a regra prática é: escreva static em todos os seus métodos. Veja o que acontece se você esquecer:

public class Main {
    void saudar() {
        System.out.println("Olá, Ana!");
    }

    public static void main(String[] args) {
        saudar();
    }
}
$ javac Main.java
Main.java:7: error: non-static method saudar() cannot be referenced from a static context
        saudar();
        ^
1 error

Traduzindo: "o método não estático saudar() não pode ser usado a partir de um contexto estático". O "contexto estático" é o main. A correção é colocar static antes de void. A aula static explica o assunto por inteiro; por enquanto, basta isso.

E o public do main?

O main tem public static void; os seus métodos, só static void. O public ("público") diz quem, de fora da classe, pode usar o método. Para métodos usados só dentro da própria classe, ele não faz diferença. As opções (public, private…) são o assunto de Modificadores de Acesso.


Formas diferentes de escrever métodos

1. Numa classe, com static (a forma desta aula)

É a forma que funciona em qualquer versão do Java e que você vai ver em livros, empresas e na maioria dos exemplos da internet. É a que o guia usa daqui em diante.

2. No JShell, para testar rápido

No JShell você pode declarar um método solto, sem classe e sem static, e chamá-lo na linha seguinte. Ótimo para experimentar:

$ jshell
|  Welcome to JShell -- Version 25.0.4.1
|  For an introduction type: /help intro

jshell> void saudar() {
   ...>     System.out.println("Olá, Ana!");
   ...> }
|  created method saudar()

jshell> saudar()
Olá, Ana!

jshell> /methods
|    void saudar()

jshell> /exit
|  Goodbye

O JShell confirma com created method saudar() ("método criado"). O comando /methods lista os métodos que você já criou na sessão.

Missão: no JShell abaixo, declare um método bomDia() que imprima Bom dia, Ana! e depois chame-o. Dica: dá para escrever o método numa linha só: void bomDia() { System.out.println("…"); }.

void bomDia() { System.out.println("Bom dia, Ana!"); }
bomDia()

3. Arquivo compacto, sem classe Java 25+

Desde o Java 25, um programa pequeno pode ser escrito sem a linha public class Main (os "arquivos-fonte compactos"). Nesse formato, o main e os outros métodos ficam soltos no arquivo e não precisam de static:

void main() {
    saudar();
    saudar();
}

void saudar() {
    IO.println("Olá! Bem-vindo à escola da Ana.");
}
$ javac Main.java && java Main
Olá! Bem-vindo à escola da Ana.
Olá! Bem-vindo à escola da Ana.

É prático para scripts e para aprender, mas só existe no Java 25 ou mais novo. Em versões anteriores (Java 21, 17, 11…), use a forma 1. Detalhes em Novidades do Java 17 ao 25.

Qual usar?

SituaçãoForma
Programas de verdade, exercícios deste guia, qualquer versão do JavaClasse + static void nome() { … }
Testar uma ideia em segundosJShell
Script rápido de um arquivo só, com Java 25+Arquivo compacto (void main())

Organizando um programa em métodos

A maior vantagem dos métodos não é só evitar repetição: é dar nomes às partes do programa. Compare dois main que fazem a mesma coisa:

Tudo no mainDividido em métodos
40 linhas de println, contas e if; para entender, você precisa ler tudo.mostrarCabecalho();
mostrarNotas();
mostrarRodape();
Três linhas que contam a história.

Algumas dicas para dividir bem:

  • Um método, uma tarefa. Se o nome precisa de "e" (mostrarCabecalhoECalcularMedia), provavelmente são dois métodos.
  • Nomes com verbo, que digam o que o método faz: imprimirMenu, mostrarFrutas, fecharLoja. Evite metodo1, coisa, teste.
  • Métodos curtos. Se um método passou de uma tela, veja se não dá para separar uma parte.
  • Copiou e colou? Sinal de que aquele trecho quer virar um método.
ConvençãoBomEvite
Começa com minúsculasaudarSaudar (parece nome de classe)
camelCase para várias palavrasmostrarCabecalhomostrar_cabecalho, mostrarcabecalho
Verbo que diz a açãoimprimirBoletimboletim, m1
Sem acento nem espaçomostrarCabecalhomostrarCabeçalho (o Java aceita, mas atrapalha em outros teclados e ferramentas)

Quando dá errado

"cannot find symbol … symbol: method"
$ javac Main.java
Main.java:7: error: cannot find symbol
        saudr();
        ^
  symbol:   method saudr()
  location: class Main
1 error

O que aconteceu: "não encontrei o símbolo". A Ana declarou saudar, mas chamou saudr (faltou o a). As linhas de baixo dizem o que faltou (symbol: method saudr(), um método chamado saudr) e onde o compilador procurou (location: class Main).

Como resolver: confira o nome letra por letra, inclusive maiúsculas: Saudar e saudar são métodos diferentes. Se o nome está certo, veja se o método foi mesmo declarado na classe.

"not a statement" (faltaram os parênteses)
public class Main {
    static void saudar() {
        System.out.println("Olá, Ana!");
    }

    public static void main(String[] args) {
        saudar;
    }
}
$ javac Main.java
Main.java:7: error: not a statement
        saudar;
        ^
1 error

O que aconteceu: "não é uma instrução". Sem os parênteses, saudar é só um nome solto, e o Java não sabe o que fazer com ele.

Como resolver: toda chamada leva parênteses, mesmo vazios: saudar();.

"invalid method declaration; return type required" (faltou o void)
$ javac Main.java
Main.java:2: error: invalid method declaration; return type required
    static saudar() {
           ^
1 error

O que aconteceu: "declaração de método inválida; é obrigatório o tipo de retorno". Antes do nome, o Java exige dizer o que o método devolve. Quem não devolve nada precisa dizer isso com void.

Como resolver: static void saudar() {. A setinha ^ aponta exatamente para onde o void deveria estar.

"illegal start of expression" (método dentro do main)
public class Main {
    public static void main(String[] args) {
        void saudar() {
            System.out.println("Olá, Ana!");
        }
        saudar();
    }
}
$ javac Main.java
Main.java:3: error: illegal start of expression
        void saudar() {
        ^
Main.java:3: error: ';' expected
        void saudar() {
                   ^
2 errors

O que aconteceu: o método foi escrito dentro do main. Em Java, um método não pode morar dentro de outro. O compilador se perde e mostra dois erros; o segundo (';' expected) é consequência do primeiro.

Como resolver: tire o método de dentro do main: feche a chave do main antes e declare o método ao lado dele, dentro da classe. Conte as chaves: cada { tem o seu }. Um editor que alinha o código (veja Editores e IDEs) ajuda muito a enxergar onde cada bloco termina.

"non-static method … cannot be referenced from a static context"
$ javac Main.java
Main.java:7: error: non-static method saudar() cannot be referenced from a static context
        saudar();
        ^
1 error

O que aconteceu: o método foi declarado sem static e chamado de dentro do main, que é static.

Como resolver: por enquanto, static void saudar(). Veja Por que static?

"method … is already defined" (dois métodos com o mesmo nome)
$ javac Main.java
Main.java:6: error: method saudar() is already defined in class Main
    static void saudar() {
                ^
1 error

O que aconteceu: "o método saudar() já foi definido na classe Main". A Ana colou o método duas vezes. Se dois métodos tivessem o mesmo nome, o Java não saberia qual chamar.

Como resolver: apague um deles ou dê outro nome. (Existe um caso em que dois métodos podem ter o mesmo nome: quando recebem informações diferentes. Isso se chama sobrecarga.)


Referência

EscritaO que éExemplo
static void nome() { … }Declara um método sem parâmetros que não devolve nadastatic void saudar() { System.out.println("Oi"); }
nome();Chama (executa) o métodosaudar();
staticMétodo da classe; necessário para ser chamado do mainveja static
voidO método não devolve valorveja Valores de Retorno
( )Lista de parâmetros (vazia aqui)veja Parâmetros
{ }Corpo: as instruções do métodoquantas linhas quiser
/methods (JShell)Lista os métodos criados na sessão| void saudar()

Missão final: organize a loja

Missão: o main abaixo faz tudo sozinho. Crie três métodos, boasVindas(), listarFrutas() e despedir(), cada um com uma das linhas, e deixe no main só as três chamadas. A saída deve continuar igual.

public class Main {
    public static void main(String[] args) {
        System.out.println("Bem-vindo à Loja da Ana");
        System.out.println("Frutas: maçã, banana, uva");
        System.out.println("Volte sempre!");
    }
}
public class Main {
    static void boasVindas() {
        System.out.println("Bem-vindo à Loja da Ana");
    }

    static void listarFrutas() {
        System.out.println("Frutas: maçã, banana, uva");
    }

    static void despedir() {
        System.out.println("Volte sempre!");
    }

    public static void main(String[] args) {
        boasVindas();
        listarFrutas();
        despedir();
    }
}

Exercícios

1. A palavra que falta

Complete a declaração de um método que só imprime (não devolve nada):

static saudar() {

2. Chamar o método

Complete a linha do main que executa o método mostrarMenu:

3. O modificador esquecido

O javac disse non-static method imprimir() cannot be referenced from a static context. Que palavra falta antes de void na declaração?

void imprimir() {

4. Um programa declara o método avisar(), mas o main nunca o chama. O que acontece quando o programa roda?

5. O main tem as linhas System.out.println("A");, b(); e System.out.println("C");. O método b() imprime B. Qual é a saída?

6. Onde um método deve ser declarado?


Resumo

  • Um método é um bloco de código com nome, como uma receita: declarado uma vez, chamado quantas vezes quiser.
  • Declaração: static void nome() { … }. void = não devolve nada; ( ) = lista de parâmetros; { } = corpo.
  • Chamada: nome();. Sem parênteses é erro (not a statement).
  • O Java pula para o método, executa o corpo e volta para a linha seguinte de quem chamou.
  • Métodos ficam dentro da classe e fora de outros métodos; a ordem entre eles não importa.
  • Por enquanto, use static em todos: o main é static e só chama direto métodos static (static).
  • Divida o programa em métodos curtos, com nomes de verbo em camelCase.