Qual é o tipo de uma expressão Lambda?

1 Lambda precisa ter um tipo funcional Lambdas não podem ser atribuídas a tipos que não são interfaces funcionais, como Object. Exemplo que não compila: Object o = () -> { System.out.println("eu sou um runnable!"); }; new Thread(o).start(); // Erro 2 Lambda atribuída corretamente a uma interface funcional Atribuindo explicitamente para Runnable: Runnable r = () -> { System.out.println("eu sou um runnable!"); }; new Thread(r).start(); // Correto 3 Lambda passada diretamente como argumento Quando passamos diretamente no construtor, o compilador usa o contexto para inferir o tipo: new Thread(() -> { System.out.println("eu sou um runnable?"); }).start(); O construtor Thread(Runnable r) espera um Runnable, então o compilador infere que a lambda é Runnable. 4 Target Type O tipo esperado pelo compilador baseado no contexto é chamado de Target Type. O Target Type permite: Inferir o tipo da expressão lambda; Reconhecer que uma mesma lambda pode representar diferentes interfaces funcionais. Exemplo com mesma expressão lambda e diferentes tipos: Callable c = () -> "retorna uma String"; PrivilegedAction p = () -> "retorna uma String"; Na primeira linha: Callable. Na segunda linha: PrivilegedAction. O Target Type define o significado. 5 O mesmo acontece com Method Reference A method reference também usa Target Type para inferência. Exemplo com method reference Callable c = callable::call; PrivilegedAction action = callable::call; A mesma referência callable::call pode se adaptar a diferentes interfaces. 6 Diferença entre Lambda e Method Reference Method references tornam a inferência mais forte, porque o tipo está mais explícito. Além disso, é permitida a conversão entre interfaces funcionais compatíveis. Exemplo: ExemploTargetType.java

Apr 29, 2025 - 23:10
 0
Qual é o tipo de uma expressão Lambda?

1 Lambda precisa ter um tipo funcional
Lambdas não podem ser atribuídas a tipos que não são interfaces funcionais, como Object.

Exemplo que não compila:

Object o = () -> {
System.out.println("eu sou um runnable!");
};
new Thread(o).start(); // Erro

2 Lambda atribuída corretamente a uma interface funcional
Atribuindo explicitamente para Runnable:

Runnable r = () -> {
System.out.println("eu sou um runnable!");
};
new Thread(r).start(); // Correto

3 Lambda passada diretamente como argumento
Quando passamos diretamente no construtor, o compilador usa o contexto para inferir o tipo:

new Thread(() -> {
System.out.println("eu sou um runnable?");
}).start();

O construtor Thread(Runnable r) espera um Runnable, então o compilador infere que a lambda é Runnable.

4 Target Type

O tipo esperado pelo compilador baseado no contexto é chamado de Target Type.

O Target Type permite:

  • Inferir o tipo da expressão lambda;

  • Reconhecer que uma mesma lambda pode representar diferentes interfaces funcionais.

Exemplo com mesma expressão lambda e diferentes tipos:

Callable c = () -> "retorna uma String";
PrivilegedAction p = () -> "retorna uma String";

Na primeira linha: Callable.
Na segunda linha: PrivilegedAction.
O Target Type define o significado.

5 O mesmo acontece com Method Reference

A method reference também usa Target Type para inferência.

Exemplo com method reference
Callable c = callable::call;
PrivilegedAction action = callable::call;

A mesma referência callable::call pode se adaptar a diferentes interfaces.

6 Diferença entre Lambda e Method Reference
Method references tornam a inferência mais forte, porque o tipo está mais explícito.

Além disso, é permitida a conversão entre interfaces funcionais compatíveis.

Exemplo: ExemploTargetType.java