世界上任何一個Java開發者都用過下面這些接口中的至少一個:java.lang.Runnable, java.awt.event.ActionListener, java.util.Comparator, java.util.concurrent.Callable。上述接口都有一個共同的特性,那就是在它們的接口定義中都只聲明瞭惟一一個方法。JDK中還有許多這樣的接口,一樣Java開發者也建立了大量的這種接口。這類接口也被稱之爲單抽象方法接口(Single Abstract Method interfaces / SAM interfaces)。一種流行方法是建立一個匿名內部類來使用這些接口,好比:java
public class AnonymousInnerClassTest{ public static void main(String... args){ new Thread(new Runnable(){ @Override public void run(){ System.out.println("A thread created and running..."); } }).start(); } }
在Java8中和單抽象方法接口(SAM interfaces)一樣的概念被建立並稱之爲函數式接口(Functional interfaces)。它們能夠使用在Lambda表達式,方法引用和構造方法引用。還有一個註解被引入 ---- @FunctionalInterface 它可用於編譯器級別,當接口註釋不是一個有效的函數式接口就會報錯。讓咱們來看一個簡單的函數式接口:express
@FunctionalInterface public interface SimpleFuncInterface{ public void doWork(); }
這個接口一樣能夠聲明來自java.lang.Object類中的抽象方法,但任然能夠被稱爲函數式接口:ide
@FunctionalInterface public interface SimpleFuncInterface{ public void doWork(); public String toString(); public boolean equals(Object o); }
一旦你在其中加入了其餘的抽象方法,那麼編譯器或IDE就會標記一個錯誤,以下圖: 函數
接口可以繼承另一個接口,當繼承於一個函數式接口切並未聲明新的抽象方法時,這個新的接口仍然是函數式接口。一個接口能夠包含有一個抽象方法和若干默認方法(Default methods),此時這個接口依然被稱爲函數式接口。關於默認方法的請見:{}翻譯
@FunctionalInterface public interface ComplexFunctionalInterface extends SimpleFuncInterface{ default public void doSomeWork(){ System.out.println("Doing some work in interface impl..."); } default public void doSomeOtherWork(){ System.out.println("Doing some other work in interface impl..."); } }
上例中的接口依然是一個有效的函數式接口。如今咱們來對比看看使用lambda表達式和匿名內部類實現函數式接口:code
/* * Implementing the interface by creating an anonymous inner class * versus using lambda expression. */ public class SimpleFuncInterfaceTest{ public static void main(String... args){ // Anonymous inner class carryOutWork(new SimpleFuncInterface(){ @Override public void doWork(){ System.out.println("Do work in SimpleFun impl..."); } }); // Lambda expression carryOutWork(()->System.out.println("Do work in lambda exp impl...")); } public static void carryOutWork(SimpleFuncInterface sfi){ sfi.doWork(); } }
結果應該輸出繼承
Do work in SimpleFun impl...
Do work in lambda exp impl...接口
本文翻譯自:Introduction to Functional Interfaces – A concept recreated in Java 8ci