Parâmetros Formais e Reais em Java
Em Java, a distinção entre parâmetros formais e reais é essencial para compreender como os métodos manipulam dados durante a chamada. Parâmetros formais atuam como variáveis locais no escopo do método, enquanto parâmetros reais fornecem os valores efetivos que inicializam essas variáveis. Este meacnismo segue o princípio de passagem por valor, afetando diferentes comportamentos para tipos primitivos e referências a objetos.
Parâmetros Formais
- Definição: Declarados na assinatura do método, os parâmetros formais são placeholders que definem os tipos e quantidades de dados esperados. Eles existem apenas durante a execução do método.
- Papel: Servem como pontos de entrada para dados externos, permitindo que o método processe informações fornecidas pelo invocador.
- Características: O número e os tipos dos parâmetros formais devem corresponder exatamente aos argumentos usados na chamada do método. Após a conclusão da execução, a memória alocada para eles é liberada.
Parâmetros Reais
- Definição: São os valores concretos ou variáveis passados durante a invocação do método. Eles podem ser literais, variáveis, expressões ou resultados de avaliações.
- Papel: Inicializam os parâmetros formais, efetivamente transferindo dados para o método. A ordem de avaliação dos argumentos não impacta o resultado devido à passagem por valor.
- Características: Devem ser compatíveis em tipo e quantidade com os parâmetros formais definidos no método. Podem representar tanto valores primitivos quanto referências a objetos.
Mecanismo de Passagem por Valor
Ao chamar um método, os valores dos parâmetros reais são copiados para os parâmetros formais, implementando a passagem por valor. Para tipos primitivos (como int ou double), uma cópia do valor numérico é criada, isolando as modificações internas da variável original. Para objetos, uma cópia da referência é passada, mantendo o vínculo com o mesmo objeto na memória heap. Isso permite que o método altere o estado interno do objeto, mas não reatribua a referência original.
public class CalculadoraSalario {
// Método com parâmetros formais
public double calcularBonus(double salarioBase, int anosServico) {
double bonus = salarioBase * 0.1 * anosServico;
return bonus;
}
public static void main(String[] args) {
CalculadoraSalario calc = new CalculadoraSalario();
double salarioFuncionario = 5000.0;
int tempoEmpresa = 5;
// Chamada com parâmetros reais
double valorBonus = calc.calcularBonus(salarioFuncionario, tempoEmpresa);
System.out.println("Bônus calculado: R$" + valorBonus);
}
}
Diferenças entre Passagem por Valor e Referência
Embora o termo "passagem por referência" seja ocasionalmente usado em Java, a linguagem adota estritamente a passagem por valor. Para tipos primitivos, a cópia do valor garante que alterações no método não afetem a variável original. Para objetos, a cópia da referência permite modificar o estado do objeto subjacente, mas reatribuir a referência no método não altera a referência original no escopo chamador.
public class TesteParametros {
public static void main(String[] args) {
int quantidade = 8;
String item = "Livro";
alterarQuantidade(quantidade);
alterarItem(item);
System.out.println("Após chamada - Quantidade: " + quantidade);
System.out.println("Após chamada - Item: " + item);
}
static void alterarQuantidade(int qtd) {
qtd = 20; // Modifica cópia local, sem efeito na variável original
}
static void alterarItem(String produto) {
produto = "Caderno"; // Reatribui cópia da referência, sem afetar referência original
System.out.println("Item modificado dentro do método: " + produto);
}
}
Neste exemplo, quantidade permanece inalterada após a chamada de alterarQuantidade, pois recebe uma cópia do valor primitivo. Para item, a reatribuição dentro de alterarItem não afeta a referência original, demonstrando que mesmo para objetos, a passagem por valor prevalece no nível da referência.