热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

Java中闭包的争论以及闭包的定义和特性

闭包一直是Java社区中争论不断的话题,很多语言都支持闭包这个语言特性,闭包定义了一个依赖于外部环境的自由变量的函数,这个函数能够访问外部环境的变量。本文以JavaScript的一个闭包为例,介绍了闭包的定义和特性。

点击关注程序员港湾,每天给你一点成长

闭包一直都是Java社区中争论不断的话题,很多语言例如Javascript,RubyPython等都支持闭包这个语言特性,闭包功能强大且灵活,并没有显式地支持它,但其实中也存在着所谓的”闭包”.

闭包

定义一个闭包的要点如下:

一个依赖于外部环境的自由变量的函数.

这个函数能够访问外部环境的.

也就是说,外部环境持有内部函数所依赖的 自由变量 ,由此对内部函数形成了闭包.

自由变量

那么什么是自由变量呢?自由变量 就是在函数自身作用域之外的变量,一个函数f(x)=x+y" tabindex="0" class="MathJax"> f ( x ) = x + y,其中y就是,它并不是这个函数自身的自变量,而是通过外部环境提供的.

下面以Javascript的一个闭包为例:

1

2

3

4

5

function Add ( y ){

returnfunction ( x )

x + y;

}

对于内部函数function(x)来说,.而是函数Add(y)内的参数,所以对内部函数形成了一个闭包.

这个闭包将自由变量y与内部函数绑定在了一起,也就是说,当函数执行完毕后,它不会随着函数调用结束后被回收(不能在栈上分配空间).

varadd_function = Add(5);// 这时y=5,并且与返回的内部函数绑定在了一起

result = add_function(10// x=10,返回最终的结果 10 + 5 = 15

Java中的闭包

Java与又或者其他支持闭包的语言不同,它是一个基于类的面向对象语言,也就是说一个方法所用到的 自由变量 永远都来自于其所在类的实例的.

6

7

class AddUtils

privateinty =;

public int add ( int x)

retrun x + y;

这样一个方法add(x)拥有一个参数x与一个,它的返回值也依赖于这个.想要正常工作的话,就必须依赖于AddUtils类的一个实例,不然它无法知道的值是多少,也就是未与进行绑定.

严格上来说,中的应该为this,这是因为也是通过关键字来访问的.

所以说,在中闭包其实无处不在,只不过我们难以发现而已.但面向对象的语言一般都不把类叫成闭包,这是一种习惯.

中的内部类就是一种典型的闭包结构.

8

9

10

11

12

publicclass Outer

class Inner

x =

public int add ()

内部类通过一个指向外部类的引用来访问外部环境中的,由此形成了一个闭包.

匿名内部类

13

14

15

16

public interface AnonInner ()

int add ()

public AnonInner getAnonInner ( final int x)

final

newAnonInner() {

getAnonInner(x)方法返回了一个匿名内部类AnonInner,匿名内部类不能显式地声明构造函数,也不能对构造函数传参,且返回的是一个接口,但它的add()方法实现中用到了两个(),也就是说外部方法对这个匿名内部类构成了闭包.

但我们发现都被加上了final修饰符,这是因为对闭包支持的不完整导致的.

对于的捕获策略有以下两种:

capture-by-value: 只需要在创建闭包的地方把捕获的值拷贝一份到对象里即可.Java的匿名内部类和Java 8新的lambda表达式都是这样实现的.

capture-by-reference: 把被捕获的局部变量“提升”(hoist)到对象里.C#的匿名函数(匿名委托/lambda表达式)就是这样实现的.

只实现了capture-by-value,但又没有对外说明这一点,为了以后能进一步扩展成支持capture-by-reference留后路,所以干脆就不允许向被捕获的变量赋值,所以这些需要强制加上修饰符(在Jdk8中似乎已经没有这种强制限制了).

作者: SylvanasSun

源自:https://sylvanassun.github.io/2017/07/30/2017-07-30-JavaClosure/

声明:文章著作权归作者所有,如有侵权,请联系小编删除。

感谢 · 转发 欢迎大家留言



推荐阅读
author-avatar
isme7
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有