所謂的函數式接口,固然首先是一個接口,而後就是在這個接口裏面只能有一個抽象方法。java
這種類型的接口也稱爲SAM接口,即Single Abstract Method interfaces。ide
它主要用在Lambda表達式和方法引用(實際上也可認爲是Lambda表達式)上。函數
如定義了一個函數式接口以下:測試
@FunctionalInterface interface GreetingService { void sayMessage(String message); }
使用Lambda表達式來表示該接口的一個實現(注:JAVA 8 以前通常是用匿名類實現的):spa
GreetingService greetService1 = message -> System.out.println("Hello " + message);
Java 8爲函數式接口引入了一個新註解@FunctionalInterface,主要用於編譯級錯誤檢查,加上該註解,當你寫的接口不符合函數式接口定義的時候,編譯器會報錯。code
正確例子,沒有報錯:繼承
@FunctionalInterface interface GreetingService { void sayMessage(String message); }
錯誤例子,接口中包含了兩個抽象方法,違反了函數式接口的定義,Eclipse報錯提示其不是函數式接口。接口
提醒:加不加@FunctionalInterface對於接口是否是函數式接口沒有影響,該註解知識提醒編譯器去檢查該接口是否僅包含一個抽象方法ip
函數式接口裏是能夠包含默認方法,由於默認方法不是抽象方法,其有一個默認實現,因此是符合函數式接口的定義的;ci
以下代碼不會報錯:
@FunctionalInterface interface GreetingService { void sayMessage(String message); default void doSomeMoreWork1() { // Method body } default void doSomeMoreWork2() { // Method body } }
函數式接口裏是能夠包含靜態方法,由於靜態方法不能是抽象方法,是一個已經實現了的方法,因此是符合函數式接口的定義的;
以下代碼不會報錯:
@FunctionalInterface interface GreetingService { void sayMessage(String message); static void printHello(){ System.out.println("Hello"); } }
函數式接口裏是能夠包含Object裏的public方法,這些方法對於函數式接口來講,不被當成是抽象方法(雖然它們是抽象方法);由於任何一個函數式接口的實現,默認都繼承了Object類,包含了來自java.lang.Object裏對這些抽象方法的實現;
以下代碼不會報錯:
@FunctionalInterface interface GreetingService { void sayMessage(String message); @Override boolean equals(Object obj); }
java.lang.Runnable,
java.awt.event.ActionListener,
java.util.Comparator,
java.util.concurrent.Callable
java.util.function包下的接口,如Consumer、Predicate、Supplier等
沒有任何參數的函數式接口
Display.java
package us.suselinks.learningjava8; @FunctionalInterface public interface Display { void show(); }
包含一個參數的函數式接口
Circle.java
package us.suselinks.learningjava8; @FunctionalInterface public interface Circle { double area(double radius); }
包含兩個參數的函數式接口
Adder.java
package us.suselinks.learningjava8; @FunctionalInterface public interface Adder { int add(int number1, int number2); }
測試函數式接口
FunctionalInterfaceDemo.java
package FunctionalInterfaceDemo; import us.suselinks.learningjava8.Adder; import us.suselinks.learningjava8.Circle; import us.suselinks.learningjava8.Display; public class FunctionalInterfaceDemo { public static void main(String[] args) { // 沒有任何參數的函數式接口 Display display = () -> System.out.println("showed up"); display.show(); // 包含一個參數的函數式接口 Circle circle = (num) -> Math.PI * num * num; double res = circle.area(5.0); System.out.println(res); // 包含兩個參數的函數式接口 Adder adder = (int a, int b) -> a + b; int rs = adder.add(15, 20); System.out.println(rs); } } 輸出: showed up 78.53981633974483 35