No Java, qualquer interface com um único método abstrato já é considerada uma interface funcional. Isso significa que não é necessário fazer nenhuma alteração para que ela possa ser usada com expressões lambda.
Criando uma Interface Funcional
Por exemplo, suponha que temos a interface Validador que verifica se um dado é válido:
interface Validador<T> {boolean valida(T t);}interface Validador<T> { boolean valida(T t); }interface Validador<T> { boolean valida(T t); }
Enter fullscreen mode Exit fullscreen mode
Antes do Java 8, precisaríamos de uma classe anônima para instanciar essa interface:
Validador<String> validadorCEP = new Validador<String>() {public boolean valida(String valor) {return valor.matches("[0-9]{5}-[0-9]{3}");}};Validador<String> validadorCEP = new Validador<String>() { public boolean valida(String valor) { return valor.matches("[0-9]{5}-[0-9]{3}"); } };Validador<String> validadorCEP = new Validador<String>() { public boolean valida(String valor) { return valor.matches("[0-9]{5}-[0-9]{3}"); } };
Enter fullscreen mode Exit fullscreen mode
Expressões Lambda
A partir do Java 8, podemos substituir a classe anônima por uma expressão lambda, tornando o código mais simples:
Validador<String> validadorCEP =valor -> {return valor.matches("[0-9]{5}-[0-9]{3}");};Validador<String> validadorCEP = valor -> { return valor.matches("[0-9]{5}-[0-9]{3}"); };Validador<String> validadorCEP = valor -> { return valor.matches("[0-9]{5}-[0-9]{3}"); };
Enter fullscreen mode Exit fullscreen mode
E podemos reduzir ainda mais, removendo o return, as chaves {} e o ponto e vírgula ;:
Validador<String> validadorCEP =valor -> valor.matches("[0-9]{5}-[0-9]{3}");Validador<String> validadorCEP = valor -> valor.matches("[0-9]{5}-[0-9]{3}");Validador<String> validadorCEP = valor -> valor.matches("[0-9]{5}-[0-9]{3}");
Enter fullscreen mode Exit fullscreen mode
Agora, a validação do CEP ocupa apenas uma linha!
A Anotação @FunctionalInterface
Para evitar que alguém modifique a interface acidentalmente, podemos usar a anotação @FunctionalInterface:
@FunctionalInterfaceinterface Validador<T> {boolean valida(T t);}@FunctionalInterface interface Validador<T> { boolean valida(T t); }@FunctionalInterface interface Validador<T> { boolean valida(T t); }
Enter fullscreen mode Exit fullscreen mode
Se tentarmos adicionar um segundo método abstrato, o compilador gera um erro:
@FunctionalInterfaceinterface Validador<T> {boolean valida(T t);boolean outroMetodo(T t); // ERRO!}@FunctionalInterface interface Validador<T> { boolean valida(T t); boolean outroMetodo(T t); // ERRO! }@FunctionalInterface interface Validador<T> { boolean valida(T t); boolean outroMetodo(T t); // ERRO! }
Enter fullscreen mode Exit fullscreen mode
Erro gerado:
java: Unexpected @FunctionalInterface annotationValidador is not a functional interfacemultiple non-overriding abstract methods found in interfacejava: Unexpected @FunctionalInterface annotation Validador is not a functional interface multiple non-overriding abstract methods found in interfacejava: Unexpected @FunctionalInterface annotation Validador is not a functional interface multiple non-overriding abstract methods found in interface
Enter fullscreen mode Exit fullscreen mode
A anotação não é obrigatória, mas garante que a interface continue sendo funcional no futuro.
Conclusão
Interfaces com um único método abstrato são automaticamente funcionais.
Podem ser instanciadas com expressões lambda em vez de classes anônimas.
A anotação @FunctionalInterface protege a interface contra modificações acidentais.
Esse recurso torna o código mais legível, curto e eficiente!
原文链接:Capítulo 3.2 e 3.3: Criando Sua Própria Interface Funcional usando anotação
暂无评论内容