前几天在学习JavaScript并且复习Go语言,都看到了一个闭包的概念,因为之前一直使用的是java,同时觉得闭包应用很有趣,就想探究一下闭包在java中的使用。因为作者水平有限,如有不足之处请赐教。
首先是闭包的定义:
闭包是由函数及其相关的引用环境组合而成的实体(即:闭包=函数+引用环境),简单来说引用环境是外部(为一个外部变量),函数是内部,这样的说法有助于我们理解之后说的内容。
对于 闭 的理解:
闭,封闭的不是外部空间,一个函数怎么可以封闭外部空间呢?封闭的是内部空间(举个例子,你在国内隔离,是隔离的个人还是隔离了国家?)。具体而言,是将外部的引用(必须是引用可以修改)拷贝一份在内部,这样的话实现了内外环境的分离。
在哪里存储
我们都知道堆空间和栈空间可以存储。一般而言,堆空间存活时间肯定是长于栈空间的。同时,如果实在栈空间上的,会导致方法调用完,栈销毁,再用引用会有危险。所以Go的编译器在处理到这个闭包时,会使用escape analyze来识别变量y的作用域,当发现变量y被一个闭包所引用时,就会把y转移到堆中(这一过程称为变量逃逸)。
JS是通过变量作用域&作用域链来解决这个事情的。
在java中的闭包
这个就相当于内部类或者 lambda表达式,但是在Java里面匿名内部类使用的外部变量必须声明为final,在lambda中默认是final。所以这个拷贝就是一个值的拷贝,所以java中的闭包都是残缺的。java中不能保证外部类和匿名内部类同时回收,导致匿名内部类里面的值是值拷贝,不是内部类的拷贝引用。
引用参考:
https://juejin.cn/post/6844903655510917128
https://www.zhihu.com/question/34210214
https://blog.csdn.net/sunshoupo211/article/details/28596697