Interfaces funcionais personalizadas
Defina a sua própria com @FunctionalInterface.
Interfaces funcionais personalizadas é uma aula grátis de Java Academy no CoddyKit. Esta é a aula 4 de 4. Você pode ler a aula completa abaixo gratuitamente — depois pratica ao vivo no navegador com um editor de código integrado e um tutor de IA 24/7. Faz parte do caminho de aprendizado de Java Academy, e seu progresso é sincronizado entre a web e o app CoddyKit. O curso de Java Academy inclui 4 aulas no total.
O que torna uma interface funcional
Uma interface funcional tem exatamente um método abstrato (SAM). Esse único método é o que uma expressão lambda implementa.
- Métodos padrão e estáticos não contam para o limite.
interface Greeter {
String greet(String name);
}
public class Main {
public static void main(String[] args) {
Greeter g = name -> "Hello, " + name;
System.out.println(g.greet("Ada"));
}
}A anotação @FunctionalInterface
@FunctionalInterface instrui o compilador a impor a regra de um único método abstrato. Se você adicionar acidentalmente um segundo método abstrato, a compilação falhará.
@FunctionalInterface
interface Calculator {
int compute(int a, int b);
}
public class Main {
public static void main(String[] args) {
Calculator add = (a, b) -> a + b;
System.out.println(add.compute(3, 4));
}
}Por que a anotação ajuda
A anotação documenta a intenção e protege o contrato. Sem ela, a interface ainda funciona como funcional, mas alguém da equipe poderia quebrá-la adicionando outro método abstrato.
@FunctionalInterface
interface Transformer {
String apply(String input);
}
public class Main {
public static void main(String[] args) {
Transformer reverse = s -> new StringBuilder(s).reverse().toString();
System.out.println(reverse.apply("abc"));
}
}Interface personalizada com genéricos
Sua interface pode ser genérica, assim como as interfaces integradas.
@FunctionalInterface
interface Converter<S, T> {
T convert(S source);
}
public class Main {
public static void main(String[] args) {
Converter<String, Integer> toInt = Integer::parseInt;
System.out.println(toInt.convert("123") + 1);
}
}Métodos default são permitidos
Uma interface funcional pode ter métodos default. Eles adicionam comportamento sem quebrar a regra de um único método abstrato.
@FunctionalInterface
interface Operation {
int apply(int x);
default Operation then(Operation next) {
return x -> next.apply(this.apply(x));
}
}
public class Main {
public static void main(String[] args) {
Operation inc = x -> x + 1;
Operation dbl = x -> x * 2;
System.out.println(inc.then(dbl).apply(5));
}
}Métodos estáticos também são permitidos
Métodos estáticos podem funcionar como fábricas, de modo semelhante a Function.identity().
@FunctionalInterface
interface Mapper {
int map(int x);
static Mapper identity() {
return x -> x;
}
}
public class Main {
public static void main(String[] args) {
System.out.println(Mapper.identity().map(99));
}
}Lançamento de exceções verificadas
Se o seu método abstrato declarar uma exceção verificada, a expressão lambda poderá lançá-la. A Function integrada não pode fazer isso, o que é uma das razões para definir a sua própria.
@FunctionalInterface
interface RiskyParser {
int parse(String s) throws NumberFormatException;
}
public class Main {
public static void main(String[] args) {
RiskyParser p = Integer::parseInt;
System.out.println(p.parse("77"));
}
}Passagem de interfaces personalizadas para métodos
Sua interface se torna um tipo de parâmetro, permitindo que quem chama forneça comportamento por meio de expressões lambda.
@FunctionalInterface
interface IntCombiner {
int combine(int a, int b);
}
public class Main {
static int reduce(int[] arr, IntCombiner c) {
int acc = arr[0];
for (int i = 1; i < arr.length; i++) acc = c.combine(acc, arr[i]);
return acc;
}
public static void main(String[] args) {
int[] data = {1, 2, 3, 4};
System.out.println(reduce(data, (a, b) -> a + b));
}
}Interface para três argumentos
O JDK fornece apenas interfaces para um e dois argumentos. Para três ou mais argumentos, defina a sua própria.
@FunctionalInterface
interface TriFunction<A, B, C, R> {
R apply(A a, B b, C c);
}
public class Main {
public static void main(String[] args) {
TriFunction<Integer, Integer, Integer, Integer> sum3 = (a, b, c) -> a + b + c;
System.out.println(sum3.apply(1, 2, 3));
}
}Referências a métodos são compatíveis com interfaces personalizadas
Qualquer método cuja assinatura corresponda ao SAM pode ser fornecido como uma referência a método.
@FunctionalInterface
interface StringTest {
boolean check(String s);
}
public class Main {
public static void main(String[] args) {
StringTest blank = String::isBlank;
System.out.println(blank.check(" "));
}
}Classe anônima versus expressão lambda
Uma expressão lambda é uma substituição concisa para uma classe anônima que implementa uma interface funcional. Ambas produzem o mesmo comportamento.
@FunctionalInterface
interface Action {
void run();
}
public class Main {
public static void main(String[] args) {
Action old = new Action() {
public void run() { System.out.println("anonymous"); }
};
Action neo = () -> System.out.println("lambda");
old.run();
neo.run();
}
}Verificação rápida
O que @FunctionalInterface garante?
Recapitulação
Você definiu suas próprias interfaces funcionais:
- Uma interface funcional tem exatamente um método abstrato (SAM).
@FunctionalInterfaceimpõe essa regra no momento da compilação.- Métodos
defaulte estáticos, genéricos e exceções verificadas são permitidos. - Interfaces personalizadas preenchem lacunas que o JDK não cobre, como funções com três argumentos ou expressões lambda que lançam exceções verificadas.
Perguntas Frequentes
A aula “Interfaces funcionais personalizadas” é grátis?
Sim — o texto completo de “Interfaces funcionais personalizadas” é grátis para ler aqui na web. Para praticá-la interativamente (um editor de código integrado e um tutor de IA 24/7) e desbloquear o restante do curso de Java Academy, atualize para CoddyKit PRO. O curso de Java Academy inclui 4 aulas no total.
O que vou aprender em “Interfaces funcionais personalizadas”?
Defina a sua própria com @FunctionalInterface. Você pratica Java Academy com código prático que executa diretamente no navegador, e um tutor de IA 24/7 responde suas dúvidas enquanto trabalha na aula.
Preciso ter experiência prévia para começar Java Academy?
Nenhuma experiência prévia é necessária. Java Academy no CoddyKit é estruturado para alunos iniciantes até avançados, então você pode começar aqui ou desde o início e aprender no seu ritmo. Esta é a aula 4 de 4.
Quanto tempo leva a aula “Interfaces funcionais personalizadas”?
A maioria das aulas CoddyKit leva cerca de 5–10 minutos. Cada uma é compacta e interativa, então você faz progresso constante e retoma exatamente de onde parou entre web e app.
Posso escrever e executar código nesta aula de Java Academy?
Sim. Cada aula de Java Academy inclui um editor de código integrado, então você escreve e executa código real direto no navegador e recebe feedback de IA instantaneamente — nenhuma configuração local necessária.
Todas as aulas deste curso
- Function e BiFunction
- Supplier e Consumer
- Predicate e composição
- Interfaces funcionais personalizadas