Interfaces Funcionales en Java 8

En esta nueva versión de la JDK se han realizada varias modificaciones en los interfaces. En el anterior artículo explique los métodos default y static y en este artículo explicaré otra de las mejoras en los interfaces, los interfaces funcionales.

La mayoría de los desarrolladores de Java hemos tenido que trabajar alguna vez con los interfaces Runnable, ActionListener, Comparator o Callable. Estos interfaces tienen en una característica en común, únicamente tienen un método abstracto. A este tipo de interfaces se les conoce como Single Abstract Method Interfaces o SAM Interfaces. La forma más común de utilizarlos es implementándolos mediante una clase anónima. Un ejemplo puede ser la implementación del método compare (interfaz Comparator) para ordenar una lista de String por orden alfabético:

En Java 8 un interfaz que tiene declarado un único método abstracto se considera un interfaz funcional y esta representado por un “Functional Descriptor”. Cuando hablamos de “Functional Descriptor” de un interfaz nos referimos a la firma del método abstracto, que está compuesta por sus parámetros, el tipo de los parámetros, el tipo que devuelve el método y las excepciones que lanza:

Los interfaces comentados anteriormente son considerados interfaces funcionales. Como por ejemplo, el interfaz Runnable que sólo define un método abstracto:

Cuando miramos más a fondo el interfaz Comparator:

Vemos que el interfaz tiene declarados dos métodos abstractos (además de varios métodos estáticos y default). Uno de estos es el método compare y otro es el método equals, que sobrescribe el método de la clase Object. Éste interfaz no se ajustaría a la anterior definición de interfaz funcional al tener dos métodos abstractos, pero en la definición de interfaz funcional se indica que en un interfaz pueden existir múltiples métodos abstractos siempre que todos menos uno sobrescriban un método público de la clase Object.

Ahora se pueden añadir métodos default o static a los interfaces pero estos métodos no son abstractos, de modo que un interfaz funcional podrá tener tantos métodos de este tipo como se desee.

Además, se ha creado una nueva anotación, @FunctionalInterface, para indicar la intención de ser un interfaz funcional, produciendo un error de compilación si el interfaz no cumple las características de un interfaz funcional. Al igual que @Override, esta notación no es obligatoria pero es recomendable su uso para mejorar la legibilidad.

Los interfaces funcionales están muy relacionados con las expresiones lambdas. Cuando ejecutamos una expresión lambda esta es convertida a un interfaz funcional, donde el cuerpo de la expresión lambda es la implementación del método abstracto. En un siguiente articulo intentaré explicar mejor las expresiones lambda para que se entienda mejora la relación que tienen con los interfaces funcionales.

  • Santiago Castellano

    me diste algun dato nuevo sobre la anotacion de una interface funcional, tampoco sabia que una interface funcional podia tener mas de un metodo abstracto siempre y cuando sobreescriban object y lo de default y los metodos de clases es una aclaracion interesante