【0011】你了解java的闭包机制吗?

【0011】你了解java的闭包机制吗?

本文将介绍java的闭包机制,阐述其定义、实现原理以及案例分析。案例有两个,第一个是JDK的ClassLoader类中实现的闭包;另一个是Junit框架中使用的闭包。闭包机制也存在不足的地方,可能会导致内存泄露,了解闭包的原理和机制,会让你得心应手,但不提倡滥用,毕竟使用到闭包的场景很少,但是却非常有用,比如:回调函数、函数式编程。

本文大纲:

1、定义

2、实现原理

3、案例分析

4、总结

一、定义

关于闭包的定义,也没有一个官方的说法,不同的编程语言可能有不同的解释,我查询资料以及结合自身对Java语言的了解,给出的定义是:

闭包可以使用一个对象引用去存储一个方法,该方法可以访问所在类的成员和属性,这个对象引用可以是一个接口。

不过在此还是提供一个稍加正式的定义,该定义来自百度百科。

闭包包含自由(未绑定到特定对象)变量;这些变量不是在这个代码块内或者任何全局上下文中定义的,而是在定义代码块的环境中定义(局部变量)。“闭包”一词来源于以下两者的结合:要执行的代码块(由于自由变量被包含在代码块中,这些自由变量以及它们引用的对象没有被释放)和为自由变量提供绑定的计算环境(作用域)。(来自百度百科)

定义可能一下子很难理解,结合下文的案例,你将焕然大悟。

二、实现原理

闭包在Java中的实现原理是使用(内部类+接口)来实现的,在接口中定义一个抽象方法,内部类实现接口并实现抽象方法,在方法中访问外部所在类的方法和属性。很理论,直接看案例吧。

三、案例分析

第一个案例:ClassLoader中的闭包

接口:授予特权的Action接口,主要用在类加载时授予一些访问检查权限。具体的访问检查操作封装在run()方法中。

【0011】你了解java的闭包机制吗?

内部类:这是ClassLoader中的一个方法,用于检查类是否有访问特定包的权限,这里使用了匿名内部类,new了一个实现,run()方法中封装了安全管理器(SecurityManager)的检查包访问操作。run()方法的调用将在访问控制器(AccessController)中的执行授权方法doPrivileged()中进行,并提供了一个访问控制上下文(AccessControlContext)。这个匿名内部类作为一个参数被传递到访问控制器中,参数也是一个对象引用。

【0011】你了解java的闭包机制吗?

第二个案例:Junit中的闭包

还是看一个简单一点的案例吧,JDK中的ClassLoader使用的闭包需要了解其业务场景,接下来看一下Junit中的闭包应用。

接口:受保护的Protectable接口中有一个protect()方法,该方法就是用于运行单元测试用例(TestCase)。可以理解为单元测试用例被运行于一个盒子中,被保护起来,类似一个黑盒。

【0011】你了解java的闭包机制吗?

内部类:这是TestResult类中的一个运行测试用例的方法,引用p指向一个实现Protectable接口的内部类,将测试用例(TestCase)的裸露运行runBare()方法封装到接口中的protect()方法中,保护起来运行。对象引用p相当于存储了一个方法,该方法访问了所在类的局部变量test的方法。最后才调用runProtected(test, p)在黑盒中运行测试用例,这是一个回调函数。Junit的设计者这一招确实高,将闭包和业务场景完美的结合了,不愧是极限编程的创始人。

【0011】你了解java的闭包机制吗?

【0011】你了解java的闭包机制吗?

四、总结

简单总结一下吧,闭包是比较重要的思想,在java开发中的某些场景也被使用到,如果你是第一次接触到java的闭包,可能你一下子很难理解,但是你结合上面的两个案例和定义原理来多揣摩,你就会焕然大悟,自然你也可以在需要时使用闭包来更好的实现你的业务需求。

感谢您的阅读,谢谢。

始发于微信公众号: Java框架源码分析

评论:

1 条评论,访客:1 条,站长:0 条
  1. staunch
    staunch发布于: 

    请问这个有什么好处呢?

发表评论