Métodos em Java
Defina e chame métodos em Java — tipos de retorno, parâmetros e o corpo do método — para organizar código reutilizável.
Um método em Java é um bloco de código com nome que você pode chamar de outros lugares do programa. Os métodos são a forma de evitar repetição: em vez de escrever o mesmo cálculo ou a mesma operação de cinco linhas em três lugares, você a coloca em um método e o chama três vezes.
Você já viu um método em todas as páginas deste livro — main. Todo programa Java é apenas uma classe com pelo menos um método que a JVM sabe como iniciar. Nesta parte do livro, veremos como escrever os seus próprios.
Anatomia de um método
Uma declaração de método tem até cinco partes: modificadores, um tipo de retorno, um nome, uma lista de parâmetros e um corpo.
public static int square(int n) {
return n * n;
}public static— modificadores.publiccontrola a visibilidade;staticsignifica que o método pertence à classe e não a uma instância. Abordaremos ambos em partes posteriores; por enquanto, todo método que você escrever em uma classe utilitária de nível superior serápublic static.int— o tipo de retorno. O tipo de valor que o método devolve ao chamador. Usevoidse não retornar nada.square— o nome. Por convenção, lowerCamelCase, e um verbo ou frase verbal que diz o que o método faz.(int n)— a lista de parâmetros. Entradas que o chamador deve fornecer. Cada parâmetro é um tipo e um nome.{ ... }— o corpo. O código que é executado quando o método é chamado.
Chamando um método
Uma vez definido, você chama um método escrevendo seu nome seguido de (...) com os valores dos argumentos:
int result = square(7); // result is 49
System.out.println(square(3) + square(4)); // 9 + 16 = 25O valor que o método retorna pode ser usado como qualquer outra expressão — atribuído a uma variável, passado como argumento, impresso, adicionado a outra coisa.
A instrução return
return faz duas coisas: interrompe o método imediatamente e envia um valor de volta ao chamador.
public static int absolute(int n) {
if (n < 0) {
return -n;
}
return n;
}Assim que return -n é executado, o método termina — o segundo return n não é executado. Um método com tipo de retorno não void deve retornar um valor em todo caminho de código possível; o compilador recusa compilar se um caminho estiver ausente.
Para métodos void, você pode usar um return; simples para sair antecipadamente, mas não precisa escrever um no final:
public static void greet(String name) {
if (name == null) return; // early exit
System.out.println("Hello, " + name);
} // implicit return at the closing braceParâmetros e argumentos
Os nomes na assinatura do método são parâmetros; os valores que você passa no local de chamada são argumentos. A distinção é pequena, mas vale a pena fazer corretamente:
public static int sum(int a, int b) { // a, b are parameters
return a + b;
}
int x = 3, y = 4;
int total = sum(x, y); // x, y are argumentsCada chamada recebe suas próprias cópias frescas dos parâmetros. Atribuir a a dentro de sum não muda x no local de chamada. O capítulo sobre passagem por valor aprofunda os detalhes.
Regras do tipo de retorno
A expressão após return deve ser compatível com atribuição ao tipo de retorno declarado — mesmo tipo ou um tipo que Java possa ampliar para ele:
public static double half(int n) {
return n / 2.0; // int / double → double, fine
}
public static int half(int n) {
return n / 2.0; // ERROR: double cannot be implicitly narrowed to int
}Se você realmente precisar reduzir, faça a conversão explicitamente: return (int)(n / 2.0);.
Métodos podem chamar outros métodos
O corpo de um método é apenas código regular — incluindo chamadas a outros métodos, inclusive a si mesmo (veja recursão):
public static int square(int n) { return n * n; }
public static int sumOfSquares(int a, int b) {
return square(a) + square(b);
}Construir métodos pequenos e de propósito único e combiná-los é o cerne de escrever Java legível.
Retornar não é imprimir
Uma confusão comum entre iniciantes: um método que imprime um valor e um que o retorna não são intercambiáveis. return devolve um valor ao chamador para que ele possa usá-lo; System.out.println apenas escreve texto no console e o chamador não recebe nada.
public static void printSquare(int n) {
System.out.println(n * n); // shows the result, returns void
}
public static int square(int n) {
return n * n; // gives the result back to the caller
}Você pode armazenar, somar ou repassar o resultado de square, mas int x = printSquare(5); não compilará — printSquare retorna void. Prefira retornar um valor e deixar o chamador decidir se o imprime; isso mantém o método reutilizável.
Sobrecarga: mesmo nome, parâmetros diferentes
Java permite que dois ou mais métodos compartilhem um nome desde que suas listas de parâmetros sejam diferentes — no número de parâmetros ou nos seus tipos. Isso é chamado de sobrecarga, e o compilador escolhe o correto com base nos argumentos que você passa:
public static int max(int a, int b) { return a > b ? a : b; }
public static double max(double a, double b) { return a > b ? a : b; }
public static int max(int a, int b, int c) { return max(max(a, b), c); }max(3, 9) chama o primeiro, max(2.5, 1.5) o segundo e max(4, 1, 7) o terceiro. O tipo de retorno sozinho não é suficiente para distinguir sobrecargas — apenas os parâmetros contam. O capítulo sobre sobrecarga de métodos cobre as regras de correspondência por completo.
Onde os métodos vivem
Um método sempre vive dentro de uma classe. Você não pode escrever uma função de nível superior como pode em JavaScript ou Python. A classe é o contêiner; o método é um de seus membros. Portanto, um arquivo completo com dois métodos se parece com isso:
public class MathUtils {
public static int square(int n) {
return n * n;
}
public static int cube(int n) {
return n * n * n;
}
}No main da mesma classe, você os chamaria como square(5) e cube(2). De uma classe diferente, você os qualificaria: MathUtils.square(5).
Um exemplo prático
O que vem a seguir
Agora que você pode declarar e chamar um método, a próxima questão é como os dados fluem para ele. O capítulo sobre parâmetros aborda os detalhes — como os argumentos se alinham com os parâmetros, quais tipos são permitidos e o que acontece quando o chamador passa objetos versus primitivos.