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.
-
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.javalink:../../../src/org/j6toj8/lambda/methodreference/MethodReference_Static.java[role=include]
Saída no console5 5
Nesse caso a única coisa que a expressão lambda faz é receber um argumento
xe repassar para o métodovalueOfdeString. 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.valueOfsatisfaz a interface funcionalFunction(recebe um argumento e retorna um valor). -
O argumento de entrada da expressão lambda
xé exatamente o mesmo passado para o métodoString.valueOf(x). -
A expressão lambda é simples: somente possui uma chamada a um método.
-
-
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.javalink:../../../src/org/j6toj8/lambda/methodreference/MethodReference_Instance.java[role=include]
Saída no console5 - 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 funcionalBiFunction(recebe dois argumentos e retorna um valor). -
Os argumentos de entrada da expressão lambda
xeysão exatamente os mesmos passados para o métodoConversor.converte(Integer, Integer). -
A expressão lambda é simples: somente possui uma chamada a um método.
-
-
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.javalink:../../../src/org/j6toj8/lambda/methodreference/MethodReference_Type.java[role=include]
Saída no console8.0 8.0
Nesse exemplo, a referência está sendo feita ao método
doubleValuedo tipoInteger. 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 argumentoxe retorna um valordouble). -
A expressão lambda recebe um argumento
xdo tipoInteger, que possui o métododoubleValueque não recebe parâmetros. -
A expressão lambda é simples: somente possui uma chamada a um método.
-
-
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.javalink:../../../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 deIntegeronde o métodocompareToserá chamado. E queyé a instância deIntegerque será passada como argumento para o métodocompareTo. -
Chamadas a um construtor também podem ser representadas como uma referência a um método.
src/org/j6toj8/lambda/methodreference/MethodReference_Constructor.javalink:../../../src/org/j6toj8/lambda/methodreference/MethodReference_Constructor.java[role=include]
Saída no console1 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.
-
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.javalink:../../../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. -
É 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.javalink:../../../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.
-
-
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.javalink:../../../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.
-
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. The Java™ Tutorials.