深刻理解Java闭包概念

闭包又称词法闭包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对象并无被释放掉。