Parâmetros de Métodos Java
Passe valores para métodos Java por meio de parâmetros e entenda a diferença entre parâmetros e argumentos.
Parâmetros são as entradas que um método declara; argumentos são os valores que você fornece ao chamá-lo. O compilador verifica se os argumentos correspondem aos parâmetros por tipo e posição, e então os entrega ao método como variáveis locais que ele pode usar em seu corpo.
Este capítulo percorre essa transferência em detalhes — a sintaxe, os tipos que você pode passar e as regras que Java aplica para converter entre eles.
Declarando parâmetros
A lista de parâmetros de um método é uma sequência separada por vírgulas de pares Tipo nome:
public static void greet(String name, int times) {
for (int i = 0; i < times; i++) {
System.out.println("Hello, " + name);
}
}Um método pode declarar zero, um ou muitos parâmetros. Cada um precisa do seu próprio tipo — não há atalho como int a, b (isso seria int a seguido de b, o que não compila).
Chamando com argumentos
No local da chamada, você passa valores na mesma ordem em que os parâmetros são declarados:
greet("Ada", 3); // name = "Ada", times = 3O compilador verifica duas coisas:
- Aridade — o número de argumentos corresponde ao número de parâmetros.
- Tipos — o tipo de cada argumento é compatível com o tipo do parâmetro correspondente.
Se alguma verificação falhar, seu programa não compilará. Passar uma String onde um int é esperado resultará em um erro como incompatible types: String cannot be converted to int.
Parâmetros são variáveis locais
Dentro do método, cada parâmetro se comporta como uma variável local inicializada com o valor do argumento:
public static int doubleIt(int n) {
n = n * 2; // legal: n is just a local
return n;
}
int x = 5;
int result = doubleIt(x); // result is 10
System.out.println(x); // still 5Reatribuir n dentro de doubleIt não afeta x no local da chamada. Cada chamada recebe sua própria cópia nova do parâmetro. É isso que as pessoas querem dizer quando dizem que Java é "passagem por valor" — cada argumento é copiado para o slot do parâmetro. Os próximos capítulos cobrem as implicações, especialmente para argumentos de objeto.
Alargamento implícito
Java alargará automaticamente um tipo numérico menor para um maior para corresponder ao parâmetro:
public static double half(double x) {
return x / 2;
}
int n = 7;
double result = half(n); // n is widened from int to doubleO alargamento é permitido porque nenhuma informação é perdida. O estreitamento não é implícito — passar um double para um parâmetro int requer uma conversão explícita:
half(7.5); // fine: double argument, double parameter
double d = 3.7;
int i = (int) d; // explicit cast
half(i); // also fineAs mesmas regras de alargamento se aplicam como na atribuição: byte → short → int → long → float → double, e char → int.
Parâmetros de objeto
Você pode passar qualquer objeto — String, um array, uma classe personalizada — declarando um parâmetro do tipo de referência correspondente:
public static int firstLength(String[] words) {
if (words.length == 0) return 0;
return words[0].length();
}
String[] colors = {"red", "green", "blue"};
System.out.println(firstLength(colors)); // 3O argumento também pode ser null, caso em que o parâmetro é null e qualquer acesso a campo ou chamada de método sobre ele lança NullPointerException. Métodos que aceitam referências geralmente verificam primeiro ou documentam que null não é permitido.
Passando null
null é compatível com todo tipo de referência para atribuição, portanto você pode passá-lo para qualquer parâmetro de objeto:
greet(null, 1);Se o método desreferenciar o parâmetro (name.length(), name.charAt(0), …), ele lança uma exceção. Um método defensivo trata null explicitamente, geralmente com uma verificação no início:
public static void greet(String name, int times) {
if (name == null) name = "stranger";
for (int i = 0; i < times; i++) {
System.out.println("Hello, " + name);
}
}Parâmetros final
Você pode marcar um parâmetro como final para proibir reatribuição dentro do método:
public static int doubleIt(final int n) {
// n = n * 2; // ERROR: cannot assign a value to final variable n
return n * 2;
}Isso não muda o que o chamador vê — apenas se o corpo tem permissão de reutilizar o slot do parâmetro. Muitos guias de estilo tratam todos os parâmetros como se fossem final, mesmo sem a palavra-chave; basta calcular novos valores em vez de mutar o parâmetro.
Ordem de avaliação dos argumentos
Quando você escreve f(a(), b(), c()), os argumentos são avaliados da esquerda para a direita, todos antes de f ser chamado. Se a() lançar uma exceção, b() e c() nunca são executados.
public static int log(String label, int value) {
System.out.println(label + " = " + value);
return value;
}
public static int sum(int a, int b, int c) {
return a + b + c;
}
sum(log("a", 1), log("b", 2), log("c", 3));
// prints:
// a = 1
// b = 2
// c = 3Esse determinismo é diferente de C e C++; em Java a ordem é fixa e previsível.
Um exemplo prático
O que vem a seguir
Você sabe como os dados entram em um método. Às vezes, você quer dois métodos com o mesmo nome mas entradas diferentes — por exemplo, um que aceita um int e outro que aceita uma String. Java permite escrever ambos de uma vez com sobrecarga de métodos.