Referência de Métodos em Java com Expressões Lambda

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.

Tags: java lambda-expressions method-references funcional interfaces-funcionais

Publicado em 6-29 16:35