Esta informação esta errada.
Chamamos de interfaces funcionais as interfaces que possuem apenas um método.
Classes, mesmo as abstratas, com apenas um método, mesmo que abstrato, não tem nada de especial e não recebem qualquer nome especial.
Veja mais: https://docs.oracle.com/javase/specs/jls/se15/html/jls-9.html#jls-9.8
Dessa forma, não é possível usar uma expressão lambda em locais onde uma classe é esperada, já que toda expressão lambda resulta numa instancia de uma interface funcional.
Experimente compilar o código abaixo:
interface Interface { void doSomething(); }
abstract class AbstractClass { abstract void doSomething(); }
public class Main {
static void testA(Interface e) { e.doSomething(); }
static void testB(AbstractClass e) { e.doSomething(); }
public static void main(String... args) {
testA(() -> System.out.println("testA"));
testB(() -> System.out.println("testB"));
}
}
Vc verá que um erro de compilação ocorrerá com a seguinte mensagem:
Main.java:12: error: incompatible types: AbstractClass is not a functional interface
testB(() -> System.out.println("testB"));
^
E só reforçando a informação dos colegas:
Quando vc cria uma classe anônima usando uma interface, na prática, o compilador irá criar automáticamente uma nova classe que implementa aquela interface.
E se usar uma classe, o compilador criará uma nova classe que a extende.
Experimente compilar o código abaixo:
// Main.java
interface Interface { void doSomething(); }
class Class { void doSomething() {} }
public class Main {
public static void main(String... args) {
new Interface() {
@Override public void doSomething() {
System.out.println("doSomething");
}
};
new Class() {};
}
}
Vc verá que o compilador gerará 5 arquivos com a extensão .class
.
Class.class
Interface.class
Main$1.class
Main$2.class
Main.class
Agora execute o seguinte comando:
javap -c 'Main$1'
O resultado será parecido com este:
Compiled from "Main.java"
class Main$1 implements Interface {
Main$1();
Code:
0: aload_0
1: invokespecial #1 // Method java/lang/Object."<init>":()V
4: return
public void doSomething();
Code:
0: getstatic #2 // Field java/lang/System.out:Ljava/io/PrintStream;
3: ldc #3 // String doSomething
5: invokevirtual #4 // Method java/io/PrintStream.println:(Ljava/lang/String;)V
8: return
}
Por último execute o seguinte comando:
javap -c 'Main$2'
O resultado será parecido com este:
Compiled from "Main.java"
class Main$2 extends Class {
Main$2();
Code:
0: aload_0
1: invokespecial #1 // Method Class."<init>":()V
4: return
}
E vejam como 2 novas classes são criadas, Main$1
e Main$2
, a primeira implementando Interface
e a segunda extendendo Class
.