【Java系列教程】一起爪哇Java 8(一)——函數式介面

來源:互聯網
上載者:User

標籤:interface   object   default   java   public   

引言

目前由於系統已經全面切換為JDK8,所以有必要系統的瞭解一下Java8的一些新特性,以便後續在日常工作中可以使用一些進階特性來提高編程效率。

因為Java8引入了函數式介面,在java.util.function包含了幾大類函數式介面聲明。這裡第一篇主要研究一下Function相關的介面。

FunctionalInterface註解

Java8的新引入,包含函數式的設計,介面都有@FunctionalInterface的註解。就像這個註解的注釋說明一樣,它註解在介面層面,且註解的介面要有且僅有一個抽象方法。具體就是說,註解在Inteface上,且interface裡只能有一個抽象方法,可以有default方法。因為從語義上來講,一個函數式介面需要通過一個***邏輯上的***方法表達一個單一函數。那理解這個單一就很重要了,單一不是說限制你一個interface裡只有一個抽象方法,單是多個方法的其他方法需要是繼承自Object的public方法,或者你要想繞過,就自己實現default。函數式介面自己本身一定是只有一個抽象方法。同時,如果是Object類的public方法,也是不允許的。官方的說明翻譯如下:

如果一個介面I,I有一組抽象方法集合M,且這些方法都不是Object類的public簽名方法,那麼如果存在一個M中的方法m,滿足:

  • m的簽名是所有M中方法簽名的子簽名。

  • m對於M中的每個方法都是傳回型別可替換的。 此時,介面I是一個函數式介面。

怎麼理解,看幾個例子。

比如:你聲明一個介面:

@FunctionalInterfacepublic interface Func {}

這會編譯錯,編譯器會告訴你*no target method*。而如果加一個方法:

@FunctionalInterfacepublic interface Func {    void run();}

這就OK了,一個函數式介面聲明好了。再加一個呢?

@FunctionalInterfacepublic interface Func {    void run();    void foo();}

不ok,明確說了只有一個抽象方法嘛。但是如果換一種函數簽名:

@FunctionalInterfacepublic interface Func {    boolean equals(Object obj);}

錯誤依舊,因為這個方法簽名是Object類的public方法。而再改一下:

@FunctionalInterfacepublic interface Func {    boolean equals(Object obj);    void run();}

這就OK了。一個抽象方法,一個Object的public方法,相安無事。Object還有其他方法,clone方法試試會怎麼樣?

@FunctionalInterfacepublic interface Func {    Object clone();    void run();}

這又不行了,因為前面明確說了,要是Object的public方法,而clone是protected的。

所以總結一句話就是:

函數式介面,有且僅有一個抽象方法,Object的public方法除外。

因為Java本身支援多介面實現,你定義一個Class可以implements多個interface。所以這個限制也沒什麼影響,如果想約定一個函數式介面來統一,也可以做一些預設的實現來達到一個介面多個抽象方法的目的,比如下面這種做法:
一個普通介面NonFunc:

public interface NonFunc {    void foo();    void voo();}

函數式介面Func:

@FunctionalInterfacepublic interface Func extends NonFunc {    void run();    default void foo() {        // do something    }    default void voo() {        // do something    }}

實現的測試類別:

public class TestJ8FunctionalInterface implements Func {    public static void main(String[] args) {        Func func = new TestJ8FunctionalInterface();        func.run();        func.foo();        func.voo();    }    @Override    public void run() {        System.out.println("run");    }    @Override    public void foo() {        System.out.println("foo");    }    @Override    public void voo() {        System.out.println("voo");    }}

函數式介面的一大特性就是可以被lambda運算式和函數參考資料表達式代替。也就是說聲明這樣的介面,是可以靈活的以方法來傳參。看個例子:

public class TestJ8FunctionalInterface2 {    public static void main(String[] args) {        TestJ8FunctionalInterface2 testJ8FunctionalInterface2 = new TestJ8FunctionalInterface2();        // lambda        testJ8FunctionalInterface2.test(10, () -> System.out.println("A customed Func."));        // method reference        testJ8FunctionalInterface2.test(100, testJ8FunctionalInterface2::customedFunc);    }    public void customedFunc() {        System.out.println("A customed method reference.");    }    public void test(int x, Func func) {        System.out.println(x);        func.run();    }}

上面例子列舉了一個lambda模式和一個方法參考模式,這樣就可以利用函數式編程強大的能力,將方法作為參數了。

閱讀全文請點擊:http://click.aliyun.com/m/9152/


本文出自 “12466150” 部落格,請務必保留此出處http://12476150.blog.51cto.com/12466150/1890430

【Java系列教程】一起爪哇Java 8(一)——函數式介面

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.