As referências de métodos em Java permitem simplificar a escrita de expressões lambda quando o corpo consiste em uma única chamada de método. Elas tornam o código mais conciso e legível.
Existem quatro tipos principais de referências de métodos:
- Referência a método estático: Classe::metodoEstatico
- Referência a método de instância de um objeto específico: objeto::metodoInstancia
- Referência a método de instância de um tipo arbitrário: Classe::metodoInstancia
- Referência a construtor: Clasce::new
Referência a Método Estático
A referência a um método estático segue o padrão NomeDaClasse::metodoEstatico. O compilador infere os parâmetros e o tipo de retorno a partir do contexto da expressão lambda.
package com.exemplo.dominio;
@FunctionalInterface
public interface ProcessadorNumerico {
void executarOperacao(int valor);
}
package com.exemplo.teste;
import com.exemplo.dominio.ProcessadorNumerico;
public class TesteReferenciaEstatica {
public static void processarNumero(int numero) {
System.out.println("Processando: " + numero * 10);
}
public static void main(String[] args) {
// Forma convencional com lambda
ProcessadorNumerico executor1 = (n) -> processarNumero(n);
executor1.executarOperacao(5);
// Forma simplificada com referência de método
ProcessadorNumerico executor2 = TesteReferenciaEstatica::processarNumero;
executor2.executarOperacao(8);
}
}
Referência a Método de Instância
Quando um método de instância é referenciado a partir de um objeto específico, utiliza-se a sintaxe objeto::metodoInstancia.
package com.exemplo.dominio;
@FunctionalInterface
public interface FornecimentoTexto {
String obterConteudo();
}
package com.exemplo.teste;
import com.exemplo.dominio.FornecimentoTexto;
public class TesteReferenciaInstancia {
public String recuperarDados() {
return "Dados recuperados do sistema";
}
public static void main(String[] args) {
TesteReferenciaInstancia instancia = new TesteReferenciaInstancia();
// Usando lambda convencional
FornecimentoTexto fornecedor1 = () -> instancia.recuperarDados();
System.out.println(fornecedor1.obterConteudo());
// Usando referência de método
FornecimentoTexto fornecedor2 = instancia::recuperarDados;
System.out.println(fornecedor2.obterConteudo());
}
}
Referência a Construtor
As referências a construtores seguem o padrão NomeDaClasse::new e permitem criar instâncias de forma abreviada.
package com.exemplo.modelo;
public class Registro {
private final String identificador;
private final String descricao;
public Registro() {
this.identificador = "REG-" + System.currentTimeMillis();
this.descricao = "Registro padrão";
}
// Getters omitted for brevity
}
package com.exemplo.dominio;
import com.exemplo.modelo.Registro;
@FunctionalInterface
public interface FabricaRegistro {
Registro criarRegistro();
}
package com.exemplo.teste;
import com.exemplo.dominio.FabricaRegistro;
import com.exemplo.modelo.Registro;
public class TesteReferenciaConstrutor {
public static void main(String[] args) {
// Criando instância via lambda
FabricaRegistro fabrica1 = () -> new Registro();
Registro reg1 = fabrica1.criarRegistro();
// Criando instância via referência de construtor
FabricaRegistro fabrica2 = Registro::new;
Registro reg2 = fabrica2.criarRegistro();
}
}
Referência a Método de Tipo Arbitrário
Este tipo de referência permite invocar métodos de instância de objetos que serão passados como parâmetro. A sintaxe é Classe::metodoInstancia.
import java.util.function.UnaryOperator;
public class TesteReferenciaTipoArbitrario {
public static void main(String[] args) {
// Calculando comprimento com lambda
UnaryOperator<string> calculadorComprimento1 = str -> str.length();
System.out.println(calculadorComprimento1.apply("Java"));
// Calculando comprimento com referência de método
UnaryOperator<string> calculadorComprimento2 = String::length;
System.out.println(calculadorComprimento2.apply("Programação"));
}
}
</string></string>
Regras para Uso
Para utilizar referências de métodos, a assinatura do método referenciado (parâmetros e retorno) deve ser compatível com o tipo funcional definido pela interface. O compilador verifica automtaicamente essa correspondência.