閉包又稱詞法閉包java
閉包最先定義爲一種包含<環境成分>和<控制成分>的實體.閉包
解釋一:閉包是引用了自由變量的函數,這個被引用的變量將和這個函數一同存在。函數
解釋二:閉包是函數和相關引用環境組成的實體。spa
注:<自由變量>:除了局部變量的其餘變量code
簡單理解:閉包可以將一個方法做爲一個變量去存儲,這個方法有能力去訪問所在類的自由變量。對象
Java中閉包實現blog
關鍵點:接口
如何用變量去存儲方法?ip
java中可以保存方法的變量指的就是普通的對象資源
如何讓這個普通對象可以訪問所在類的自由變量?
純自然的解決辦法是:內部類。內部類可以訪問外部類的全部屬性及方法。
隱藏具體實現是內部類的做用之一,如何保證隱藏具體實現的同時還能將閉包傳遞到外部使用?
讓內部類實現通用接口,而後將內部類對象向上轉型爲接口類型。
上述解決辦法就是Java最經常使用的閉包實現辦法(內部類+接口)
下面提供一個簡單的實現
public class Milk { public final static String name = "純牛奶";//名稱 private static int num = 16;//數量 public Milk() { System.out.println(name+":16/每箱"); } /** * 閉包 * @return 返回一個喝牛奶的動做 */ public Active HaveMeals() { return new Active() { public void drink() { if(num == 0) { System.out.println("木有了,都被你丫喝完了."); return; } num--; System.out.println("喝掉一瓶牛奶"); } }; } /** * 獲取剩餘數量 */ public void currentNum() { System.out.println(name+"剩餘:"+num); } } /** * 通用接口 */ interface Active { void drink(); }
使用上述實現
public class Person { public static void main(String[] args) { //買一箱牛奶 Milk m = new Milk(); Active haveMeals = m.HaveMeals(); //沒事喝一瓶 haveMeals.drink(); //有事喝一瓶 haveMeals.drink(); //看看還剩多少? m.currentNum(); } }
運行結果
純牛奶:16/每箱 喝掉一瓶牛奶 喝掉一瓶牛奶 純牛奶剩餘:14
上述例子中,經過調用Active的方法實現對Milk私有變量num進行修改。
有時候以爲直接使用set方法也能夠直接修改private變量,可是從現實生活中來講讓人去執行喝牛奶的動做比牛奶本身動手喝來的合理一些。
總結
1.實際項目中沒怎麼用過閉包,所以不能對他的好壞進行評論。
2.建議合理的使用閉包,不徹底不使用,也不能濫用。
3.特別注意:閉包會致使資源不被回收,如上例,在main方法中將m設爲null,使用haveMeals繼續調用drink方法仍然會喝掉一瓶牛奶,說明Milk對象並無被釋放掉。