函數式接口簡介 ---- 一個在Java8中重建的概念

函數式接口簡介 ---- 一個在Java8中重建的概念

世界上任何一個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就會標記一個錯誤,以下圖: funcinterface_error1函數

接口可以繼承另一個接口,當繼承於一個函數式接口切並未聲明新的抽象方法時,這個新的接口仍然是函數式接口。一個接口能夠包含有一個抽象方法和若干默認方法(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

相關文章
相關標籤/搜索