Skip to content

Latest commit

 

History

History
173 lines (152 loc) · 7.57 KB

File metadata and controls

173 lines (152 loc) · 7.57 KB

Referências a Métodos (Method Reference)

Objetivo
Develop code that uses a method reference, including refactoring a lambda expression to a method reference.
-
Desenvolver código que utiliza uma referência a método, incluindo a refatoração de uma expressão lambda para uma referência a método.

A sintaxe de referência a um método é uma novidade do Java 8. Com ela é possível fazer referência a métodos específicos, em quatro ocasiões diferentes:

  • Referências a métodos estáticos → String::valueOf

  • Referências a métodos de um objeto → instanciaDeString::isEmpty

  • Referências a métodos de um tipo de objeto (de uma classe, interface, etc) → String::isEmpty

  • Referências a construtores → String::new

É essencial lembrar das Interfaces Funcionais, das variações de sintaxe de Expressões Lambda e das definições de Interfaces Funcionais Pré-Construídas. Caso julgue necessário, reveja as seções deste capítulo.

É possível pensar nas referências a métodos como uma outra forma de escrever uma expressão lambda, caso a única coisa que sua expressão lambda faça seja chamar um outro método.

A seguir serão apresentadas as ocasiões em que são utilizadas as referências a métodos.

  1. Chamadas a métodos estáticos em expressões lambda podem virar uma referência ao método.

    src/org/j6toj8/lambda/methodreference/MethodReference_Static.java
    link:../../../src/org/j6toj8/lambda/methodreference/MethodReference_Static.java[role=include]
    Saída no console
    5
    5

    Nesse caso a única coisa que a expressão lambda faz é receber um argumento x e repassar para o método valueOf de String. Para simplificar isso, o Java 8 permite que você escreva essa mesma função lambda como foi apresentado na linha seguinte: String::valueOf.

    Só é possível representar a primeira expressão lambda na forma de um method reference porque:

    • A implementação de String.valueOf satisfaz a interface funcional Function (recebe um argumento e retorna um valor).

    • O argumento de entrada da expressão lambda x é exatamente o mesmo passado para o método String.valueOf(x).

    • A expressão lambda é simples: somente possui uma chamada a um método.

  2. Chamadas a métodos de uma instância específica também podem ser representados como uma referência a um método.

    src/org/j6toj8/lambda/methodreference/MethodReference_Instance.java
    link:../../../src/org/j6toj8/lambda/methodreference/MethodReference_Instance.java[role=include]
    Saída no console
    5 - 8
    5 - 8

    Só é possível representar a primeira expressão lambda na forma de um method reference porque:

    • A implementação de Conversor.converte(Integer, Integer) satisfaz a interface funcional BiFunction (recebe dois argumentos e retorna um valor).

    • Os argumentos de entrada da expressão lambda x e y são exatamente os mesmos passados para o método Conversor.converte(Integer, Integer).

    • A expressão lambda é simples: somente possui uma chamada a um método.

  3. Chamadas a métodos de uma classe, sem especificar a instância específica, também podem ser representados como uma referência a um método.

    src/org/j6toj8/lambda/methodreference/MethodReference_Type.java
    link:../../../src/org/j6toj8/lambda/methodreference/MethodReference_Type.java[role=include]
    Saída no console
    8.0
    8.0

    Nesse exemplo, a referência está sendo feita ao método doubleValue do tipo Integer. Só é possível representar a primeira expressão lambda na forma de um method reference porque:

    • Nossa expressão lambda satisfaz a interface funcional Function (recebe um argumento x e retorna um valor double).

    • A expressão lambda recebe um argumento x do tipo Integer, que possui o método doubleValue que não recebe parâmetros.

    • A expressão lambda é simples: somente possui uma chamada a um método.

  4. Também é possível utilizar a referência ao método de um tipo, como no exemplo anterior, mesmo que o método receba parâmetros.

    src/org/j6toj8/lambda/methodreference/MethodReference_TypeWithParam.java
    link:../../../src/org/j6toj8/lambda/methodreference/MethodReference_TypeWithParam.java[role=include]
    Saída no console
    -1
    -1

    Nesse exemplo o compilador "descobre" ainda mais coisas que nos exemplos anteriores. Ao escrever apenas a referência ao método, o compilador entende que a variável x, que vem primeiro, será a instância de Integer onde o método compareTo será chamado. E que y é a instância de Integer que será passada como argumento para o método compareTo.

  5. Chamadas a um construtor também podem ser representadas como uma referência a um método.

    src/org/j6toj8/lambda/methodreference/MethodReference_Constructor.java
    link:../../../src/org/j6toj8/lambda/methodreference/MethodReference_Constructor.java[role=include]
    Saída no console
    1
    1

    Esse exemplo é muito parecido com o anterior, com a única diferença sendo que o método referenciado é um construtor. Perceba que o construtor também recebe um parâmetro e, assim como no exemplo anterior, o compilador entende que o argumento da função lambda deve ser passado para o construtor que foi chamado.

  6. Expressões lambda complexas não podem ser convertidas em referência a método, como a expressão abaixo:

    src/org/j6toj8/lambda/methodreference/MethodReference_Complex.java
    link:../../../src/org/j6toj8/lambda/methodreference/MethodReference_Complex.java[role=include]

    Como nesse caso temos uma outra String + "2" sendo acrescentada no construtor, não há como representar isso com uma simples referência ao construtor.

  7. É possível utilizar method reference também com suas própria classes. Veja no exemplo a seguir os tipos criados pelo nosso código e as expressões lambda equivalentes com e sem referência a métodos.

    src/org/j6toj8/lambda/methodreference/MethodReference_CustomType.java
    link:../../../src/org/j6toj8/lambda/methodreference/MethodReference_CustomType.java[role=include]

    Perceba a diferença entre as expressões lambda:

    • Uma parte implementa a interface functional Function, pois recebem um argumento e retornam um valor.

    • A última implementa a interface functional Supplier, pois não recebe argumento, mas retorna um valor.

      Em caso de dúvidas, consulte novamente os tipos de interfaces funcionais nas outras seções deste capítulo.

  8. A variedade de formas para representar uma mesma expressão lambda pode ser grande, então cuidado para não se confundir.

    src/org/j6toj8/lambda/methodreference/MethodReference_Variaty.java
    link:../../../src/org/j6toj8/lambda/methodreference/MethodReference_Variaty.java[role=include]

    Você já viu todas as formas de criar uma expressão lambda, desde a mais completa até a mais simples. Tenha certeza que conhece todas essas variações para o exame de certificação.

Referências
  • Using Method References

    Boyarsky, Jeanne; Selikoff, Scott. OCP: Oracle Certified Professional Java SE 8 Programmer II Study Guide (p. 152). Wiley. Edição do Kindle.

  • Method References in Java.

  • Method References. The Java™ Tutorials.