热门标签 | 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/

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

感谢 · 转发 欢迎大家留言



推荐阅读
  • 深入理解Shell脚本编程
    本文详细介绍了Shell脚本编程的基础概念、语法结构及其在操作系统中的应用。通过具体的示例代码,帮助读者掌握如何编写和执行Shell脚本。 ... [详细]
  • 深入理解Redis的数据结构与对象系统
    本文详细探讨了Redis中的数据结构和对象系统的实现,包括字符串、列表、集合、哈希表和有序集合等五种核心对象类型,以及它们所使用的底层数据结构。通过分析源码和相关文献,帮助读者更好地理解Redis的设计原理。 ... [详细]
  • 使用Pandas高效读取SQL脚本中的数据
    本文详细介绍了如何利用Pandas直接读取和解析SQL脚本,提供了一种高效的数据处理方法。该方法适用于各种数据库导出的SQL脚本,并且能够显著提升数据导入的速度和效率。 ... [详细]
  • 作为一名 Ember.js 新手,了解如何在路由和模型中正确加载 JSON 数据是至关重要的。本文将探讨两者之间的差异,并提供实用的建议。 ... [详细]
  • 本文详细探讨了 Django 的 ORM(对象关系映射)机制,重点介绍了其如何通过 Python 元类技术实现数据库表与 Python 类的映射。此外,文章还分析了 Django 中各种字段类型的继承结构及其与数据库数据类型的对应关系。 ... [详细]
  • 本文探讨了如何在日常工作中通过优化效率和深入研究核心技术,将技术和知识转化为实际收益。文章结合个人经验,分享了提高工作效率、掌握高价值技能以及选择合适工作环境的方法,帮助读者更好地实现技术变现。 ... [详细]
  • FinOps 与 Serverless 的结合:破解云成本难题
    本文探讨了如何通过 FinOps 实践优化 Serverless 应用的成本管理,提出了首个 Serverless 函数总成本估计模型,并分享了多种有效的成本优化策略。 ... [详细]
  • 配置Windows操作系统以确保DAW(数字音频工作站)硬件和软件的高效运行可能是一个复杂且令人沮丧的过程。本文提供了一系列专业建议,帮助你优化Windows系统,确保录音和音频处理的流畅性。 ... [详细]
  • 在开发Android应用程序时,特别是在处理方向事件时,我们通常会接收到包含方位角、俯仰和滚转三个浮点数值的SensorEvent。这些值反映了设备相对于现实世界坐标系的旋转状态。对于类似迷宫的应用程序,如何允许用户以任意角度握住设备并确保应用正常工作是一个挑战。 ... [详细]
  • GIMP 2.99.2 发布:UI 采用 GTK3 实现、原生支持高分屏和 Wayland
    开源项目评选最后一周,手里的5票再不用就没用了https:www.oschina.netprojecttop_cn_2020GIMP2.99.2已发布,同时这也标志着GIMP3.0的到来,其中最显著的变化是从GTK2过渡到GTK3工具包。基于 ... [详细]
  • 本题旨在通过给定的评级信息,利用拓扑排序和并查集算法来确定全球 Tetris 高手排行榜。题目要求判断是否可以根据提供的信息生成一个明确的排名表,或者是否存在冲突或信息不足的情况。 ... [详细]
  • 自己用过的一些比较有用的css3新属性【HTML】
    web前端|html教程自己用过的一些比较用的css3新属性web前端-html教程css3刚推出不久,虽然大多数的css3属性在很多流行的浏览器中不支持,但我个人觉得还是要尽量开 ... [详细]
  • 本文详细介绍了S5P4418处理器中的定时器模块,涵盖五个定时器(Timers 0-4)的特性与配置。这些定时器不仅支持PWM输出,还具备灵活的时钟源和预分频器设置,其中Timers 0和1共享一个预分频器,而Timers 2、3和4则共享另一个预分频器。默认情况下,2nboot配置为200MHz。 ... [详细]
  • 本文介绍了多个关于JavaScript的书籍资源、实用工具和编程实例,涵盖从入门到进阶的各个阶段,帮助读者全面提升JavaScript编程能力。 ... [详细]
  • 本文详细解释了华为ENSP模拟器中常用的命令,涵盖用户模式、系统模式、接口模式和地址池视图模式下的操作。这些命令对于进行计算机网络实验至关重要,帮助用户更好地理解和配置路由器及PC机的通信。 ... [详细]
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社区 版权所有