Java深海拾遺系列(5)---函式式介面Functional Interface

FeelTouch發表於2019-04-10

函式式介面和作用

所謂的函式式介面,當然首先是一個介面,然後就是在這個介面裡面只能有一個抽象方法

這種型別的介面也稱為SAM介面,即Single Abstract Method interfaces

它們主要用在Lambda表示式和方法引用(實際上也可認為是Lambda表示式)上。

如定義了一個函式式介面如下:

@FunctionalInterface
    interface GreetingService 
    {
        void sayMessage(String message);
    }

那麼就可以使用Lambda表示式來表示該介面的一個實現(注:JAVA 8 之前一般是用匿名類實現的):

GreetingService greetService1 = message -> System.out.println("Hello " + message);

@FunctionalInterface註解

Java 8為函式式介面引入了一個新註解@FunctionalInterface,主要用於編譯級錯誤檢查,加上該註解,當你寫的介面不符合函式式介面定義的時候,編譯器會報錯。

正確例子,如上,沒有報錯

錯誤例子,介面中包含了兩個抽象方法,違反了函式式介面的定義,Eclipse報錯提示其不是函式式介面。

加不加@FunctionalInterface對於介面是不是函式式介面沒有影響,該註解知識提醒編譯器去檢查該介面是否僅包含一個抽象方法

函式式介面限制和適用

1. 函式式介面裡是可以包含預設方法,因為預設方法不是抽象方法,其有一個預設實現,所以是符合函式式介面的定義的;

@FunctionalInterface
    interface GreetingService
    {
        void sayMessage(String message);

        default void doSomeMoreWork1()
        {
            // Method body
        }

        default void doSomeMoreWork2()
        {
            // Method body
        }
    }

2. 函式式介面裡是可以包含靜態方法,因為靜態方法不能是抽象方法,是一個已經實現了的方法,所以是符合函式式介面的定義的

@FunctionalInterface
    interface GreetingService 
    {
        void sayMessage(String message);
        static void printHello(){
            System.out.println("Hello");
        }
    }

3. 函式式介面裡是可以包含Object裡的public方法,這些方法對於函式式介面來說,不被當成是抽象方法(雖然它們是抽象方法);因為任何一個函式式介面的實現,預設都繼承了Object類,包含了來自java.lang.Object裡對這些抽象方法的實現;

@FunctionalInterface
    interface GreetingService  
    {
        void sayMessage(String message);
        
        @Override
        boolean equals(Object obj);
    }

JDK中的函式式介面舉例

java.lang.Runnable,

java.awt.event.ActionListener, 

java.util.Comparator,

java.util.concurrent.Callable

java.util.function包下的介面,如Consumer、Predicate、Supplier等

參考:Functional Interface

相關文章