咸咸海风

https://github.com/xianxianhaifeng

  博客园 :: 首页 :: 博问 :: 闪存 :: 新随笔 :: :: :: 管理 ::

闭包又称词法闭包

闭包最早定义为一种包含<环境成分>和<控制成分>的实体.

解释一:闭包是引用了自由变量的函数,这个被引用的变量将和这个函数一同存在。

解释二:闭包是函数和相关引用环境组成的实体。

注:<自由变量>:除了局部变量的其他变量

 

简单理解:闭包能够 将一个方法 作为 一个变量 去存储,这个方法有能力去访问所在类的自由变量。

Java中闭包实现

关键点:

如何用变量去存储方法?

java中能够保存方法的变量指的就是普通的对象

如何让这个普通对象能够访问所在类的自由变量?

纯天然的解决办法是:内部类。内部类能够访问外部类的所有属性及方法。

隐藏具体实现是内部类的作用之一,如何保证隐藏具体实现的同时还能将闭包传递到外部使用?

让内部类实现通用接口,然后将内部类对象向上转型为接口类型。

上述解决办法就是Java最常用的闭包实现办法(内部类+接口)

 

下面提供一个简单的实现

 1 public class Milk {
 2     
 3     public final static String name = "纯牛奶";//名称
 4     
 5     private static int num = 16;//数量
 6     
 7     public Milk()
 8     {
 9         System.out.println(name+":16/每箱");
10     }
11     
12     /**
13      * 闭包
14      * @return 返回一个喝牛奶的动作
15      */
16     public Active HaveMeals()
17     {
18         return new Active()
19                 {
20                     public void drink()
21                     {
22                         if(num == 0)
23                         {
24                             System.out.println("木有了,都被你丫喝完了.");
25                             return;
26                         }
27                         num--;
28                         System.out.println("喝掉一瓶牛奶");
29                     }
30                 };
31     }
32     
33     /**
34      * 获取剩余数量
35      */
36     public void currentNum()
37     {
38         System.out.println(name+"剩余:"+num);
39     }
40 }
41 
42 /**
43  * 通用接口
44  */
45 interface Active
46 {
47     void drink();
48 }

 

使用上述实现

 1 public class Person {
 2 
 3     public static void main(String[] args) {
 4         //买一箱牛奶
 5         Milk m = new Milk();
 6         
 7         Active haveMeals = m.HaveMeals();
 8         
 9         //没事喝一瓶
10         haveMeals.drink();
11         //有事喝一瓶
12         haveMeals.drink();
13         
14         //看看还剩多少?
15         m.currentNum();
16     }
17 
18 }
19  

运行结果

纯牛奶:16/每箱
喝掉一瓶牛奶
喝掉一瓶牛奶
纯牛奶剩余:14 

上述例子中,通过调用Active的方法实现对Milk私有变量num进行修改。

 

总结

1.实际项目中没怎么用过闭包,因此不能对他的好坏进行评论。

2.建议合理的使用闭包,不完全不使用,也不能滥用。

3.特别注意:闭包会导致资源不被回收,如上例,在main方法中将m设为null,使用haveMeals继续调用drink方法仍然会喝掉一瓶牛奶,说明Milk对象并没有被释放掉。

 

 

posted on 2019-12-30 14:59  咸咸海风  阅读(1490)  评论(0编辑  收藏  举报