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.
- 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
javacmais 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 cozinha | No Java |
|---|---|
| Escrever a receita no caderno | Declarar o método (dar nome e escrever as instruções) |
| O nome da receita | O nome do método, como saudar |
| Os passos da receita | O 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.
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
Maine pode ser chamado direto pelomain. 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(…);.
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
| Passo | Onde o Java está | O que acontece |
|---|---|---|
| 1 | main, linha 3 | Imprime "1. O main começou". |
| 2 | main, linha 4 → saudar | Encontra saudar();, pula para o método e imprime a saudação. O método acabou: volta. |
| 3 | main, linha 5 | Continua de onde parou: imprime "3. Voltei para o main". |
| 4 | main, linha 6 → saudar | Pula de novo para o método. A mesma receita, seguida outra vez. |
| 5 | main, linha 7 | Imprime 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.
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. Omainé 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.
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ção | Forma |
|---|---|
| Programas de verdade, exercícios deste guia, qualquer versão do Java | Classe + static void nome() { … } |
| Testar uma ideia em segundos | JShell |
| 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 main | Dividido 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. Evitemetodo1,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ção | Bom | Evite |
|---|---|---|
| Começa com minúscula | saudar | Saudar (parece nome de classe) |
| camelCase para várias palavras | mostrarCabecalho | mostrar_cabecalho, mostrarcabecalho |
| Verbo que diz a ação | imprimirBoletim | boletim, m1 |
| Sem acento nem espaço | mostrarCabecalho | mostrarCabeçalho (o Java aceita, mas atrapalha em outros teclados e ferramentas) |
Quando dá errado
$ 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.
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();.
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.
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.
$ 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?
$ 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
| Escrita | O que é | Exemplo |
|---|---|---|
static void nome() { … } | Declara um método sem parâmetros que não devolve nada | static void saudar() { System.out.println("Oi"); } |
nome(); | Chama (executa) o método | saudar(); |
static | Método da classe; necessário para ser chamado do main | veja static |
void | O método não devolve valor | veja Valores de Retorno |
( ) | Lista de parâmetros (vazia aqui) | veja Parâmetros |
{ } | Corpo: as instruções do método | quantas 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):
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?
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
staticem todos: omainéstatice só chama direto métodosstatic(static). - Divida o programa em métodos curtos, com nomes de verbo em camelCase.