Sunday, January 6, 2013

java 8 : Functional Interfaces


In this article, we will try to learn new Java 8 concept : functional interface. It's an entry point for using lambdas and other JAVA 8 features ...

Definition from JSR 335

A functional interface is an interface that has just one abstract method, and thus represents a single function contract. (In some cases, this "single" method may take the form of multiple abstract methods with override-equivalent signatures (8.4.2) inherited from superinterfaces; in this case, the inherited methods logically represent a single method.)
In addition to the usual process of creating an interface instance by declaring and instantiating a class, instances of functional interfaces can be created with lambda expressions, method references, or constructor references.
The function descriptor of a functional interface I is a method type—type parameters, formal parameter types, return types, and thrown types—that can be used to legally override the abstract method(s) of I.

 In short, a functional interface is only one interface with just one abstract method. The goal of Functional Interface is to use JAVA 8 feature like lambdas.

Simple example


Here is a short example :

ICode.java

 package fr.dr.practice;

/**
 * Interface with just one abstract method.
 */
public interface ICode {
    String generate(int codeNumber);
}
Main.java

package fr.dr.practice;

/**
 * Created with IntelliJ IDEA.
 */
public class Main {

    public static String generateTmpCode(int newCode) {
        ICode code = new ICode() {
            @Override
            public String generate(int codeNumber) {
                return "MAIN_" + codeNumber + Math.random();
            }
        };
        return code.generate(newCode);
    }

    public static String generateTmpCodeWithLambda(int newCode) {
        ICode icode = codeNumber -> "MAIN_" + codeNumber + Math.random();
        return icode.generate(newCode);
    }

    public static void main(String[] args) {
        System.out.println(Main.generateTmpCode(12));
        System.out.println(Main.generateTmpCodeWithLambda(12));

    }
}

More complex examples

The JSR says the following :

In some cases, this "single" method may take the form of multiple abstract methods with override-equivalent signatures (8.4.2) inherited from superinterfaces; in this case, the inherited methods logically represent a single method.

So, you can make the following because equals method is public in Object class :

public interface ICode {

    String generate(int codeNumber);
    boolean equals(Object obj);
}

But you can't make this because clone method (protected Object clone() throws CloneNotSupportedException {) isn't public in Object class :

public interface ICode {

    String generate(int codeNumber);
    Object clone();
   
}

Function descriptor 

The JSR 335 add also a the concept of Functional descriptor.
Here is an example from JSR :

interface X { void m() throws IOException; }
interface Y { void m() throws EOFException; }
interface Z { void m() throws ClassNotFoundException; }
interface XY extends X, Y {}
interface XYZ extends X, Y, Z {}

// XY has descriptor ()->void throws EOFException
// XYZ has descriptor ()->void (throws nothing)

Conclusion

Functional interface permits to use lambda or other JAVA 8 features.It exists yet some functional interface (e.g : java.util.Comparator ). Java 8 has also a new package : java.util.functions which defines new Functional Interface.You could see this good blog for example with it : http://datumedge.blogspot.fr/2012/06/java-8-lambdas.html.
This article permits me to learn JAVA 8 feature.If you have comments or if you see errors, please post it ! In next article, we will study lambda feature ...