詳解Java中的閉包(Closure)

詳解Java中的閉包(Closure)

https://blog.csdn.net/lixiangminghate/article/details/70189210html

之前老是對閉包(Closure)只知其一;不知其二的,最近花時間查閱資料,不少地方都講得語焉不詳,看後仍感受雲裏霧裏的。後來仍是研究了下李剛寫的《瘋狂Java講義》,裏面講得仍是比較清楚,才終於弄清楚了閉包是怎麼回事。如今分享研究結果出來,也算是給像我原來同樣有疑惑的學習者一個參考。程序員

 

閉包(Closure)是一種能被調用對象,它保存了建立它的做用域的信息。編程

Java並不能顯式地支持閉包,但對於非靜態內部類而言,它不只記錄了其外部類的詳細信息,還保留了一個建立非靜態內部類對象的引用,而且能夠直接調用外部類的private成員,所以能夠把非靜態內部類當成面向對象領域的閉包。閉包

經過這種仿閉包的非靜態內部類,能夠很方便地實現回調功能,回調就是某個方法一旦得到了內部類對象的引用後,就能夠在合適時候反過來調用外部類的方法。所謂回調,就是容許客戶類經過內部類引用來調用其外部類的方法,這是一種很是靈活的功能。學習

 

假設有下面的Teachable接口和Programmer基類,它們都提供了一個work方法,這兩個方法的方法簽名徹底相同,但方法功能可能不同。this

interface Teachableurl

{.net

void work();htm

}對象

public class Programmer

{

private String name;

//Programmer類的兩個構造器

public Programmer(){}

public Programmer(String name)

{

this.name = name;

}

//此處省略了name屬性的setter和getter方法

...

public void work()

{

System.out.println(name + "在燈下認真敲鍵盤...");

}

}

假設如今有一我的,既是一個程序員,也是一個教師。也就是說須要定義一個特殊的類,既須要實現Teachable接口,也須要繼承Programmer父類。表面上看起來這沒有任何問題,問題是Teachable接口和Programmer父類裏包含了相同的work方法,若是採用以下代碼來定義一個特殊的TeachableProgrammer類:

public class TeachableProgrammer extends Programmer implements Teachable

{

public void work()

{

System.out.println(super.name + "教師在講臺上講解...");

}

}

顯然上面的TeachableProgrammer類只有一個work方法,這個work方法只能進行「教學」,再也不能夠進行「編程」。但實際須要TeachableProgrammer類裏既包含「教學」的work方法,也包含「編程」的work方法。

這個時候,能夠經過一個仿閉包的內部類來實現這個功能:

public class TeachableProgrammer extends Programmer

{

public TeachableProgrammer(){}

public TeachableProgrammer(String name)

{

super(name);

}

//教學工做依然由TeachableProgrammer類定義

private void teach()

{

System.out.println(getName() + "教師在講臺上講解...");

}

private class Closure implements Teachable

{

 

public void work()

{

teach();

}

}

//返回一個非靜態內部類引用,容許外部類經過該非靜態內部類引用來回調外部類的方法

public Teachable getCallbackReference()

{

return new Closure();

}

}

上面的TeachableProgrammer只是Programmer類的子類,它能夠直接調用Programmer基類的work方法,該類也包含教學的teach方法,但這個方法與Teachable接口沒有任何關係,TeachableProgrammer也不能當成Teachable使用。此時建立了一個Closure內部類,它實現了Teachable接口,並實現了教學的work方法(粗體字部分)——但這種實現是經過回調TeachableProgrammer類的teach方法實現的。若是須要讓TeachableProgrammer對象進行教學,只需調用Closure內部類(它是Teachable接口的實現類)對象的work方法便可。

TeachableProgrammer類提供了一個獲取內部類對象的方法:該方法無需返回Closure類型,只需返回所實現接口:Teachable類型便可,由於它只須要當成一個Teachable對象使用便可。

 

下面圖1是上面三個類和一個接口的類圖:

詳解Java中的閉包(Closure)和回調

圖1:類圖

圖1清楚地看出Closure內部類的做用,它可實現Teachable接口,也能夠當成Teachable使用,並且它是TeachableProgrammer的內部類,是回調TeachableProgrammer對象方法的入口,它的work方法實際上回調了TeachableProgrammer類的teach方法。

 

下面程序示範瞭如何讓TeachableProgrammer對象既執行「教學」的work方法,也執行「編程」的work方法。

public class TestTeachableProgrammer

{

public static void main(String[] args) 

{

TeachableProgrammer tp = new TeachableProgrammer("李剛");

//直接調用TeachableProgrammer類從Programmer類繼承到的work方法

tp.work();
//表面上調用的是Closure的work方法,其實是回調TeachableProgrammer的teach方法

tp.getCallbackReference().work();

}

}

上面程序中粗體字部分,代表上調用了Teachable對象(其實是Closure對象)的work方法,實際回調了TeachableProgrammer對象的teach方法。內部類對象能夠很方便地回調其外部類的屬性、方法,這樣就可讓編程更加靈活。

相關文章
相關標籤/搜索