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

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

感谢 · 转发 欢迎大家留言



推荐阅读
  • 问题描述现在,不管开发一个多大的系统(至少我现在的部门是这样的),都会带一个日志功能;在实际开发过程中 ... [详细]
  • 在Effective Java第三版中,建议在方法返回类型中优先考虑使用Collection而非Stream,以提高代码的灵活性和兼容性。 ... [详细]
  • 如何精通编程语言:全面指南与实用技巧
    如何精通编程语言:全面指南与实用技巧 ... [详细]
  • 掌握PHP编程必备知识与技巧——全面教程在当今的PHP开发中,了解并运用最新的技术和最佳实践至关重要。本教程将详细介绍PHP编程的核心知识与实用技巧。首先,确保你正在使用PHP 5.3或更高版本,最好是最新版本,以充分利用其性能优化和新特性。此外,我们还将探讨代码结构、安全性和性能优化等方面的内容,帮助你成为一名更高效的PHP开发者。 ... [详细]
  • 本文探讨了如何在PHP与MySQL环境中实现高效的分页查询,包括基本的分页实现、性能优化技巧以及高级的分页策略。 ... [详细]
  • 本文详细探讨了在Java中如何将图像对象转换为文件和字节数组(Byte[])的技术。虽然网络上存在大量相关资料,但实际操作时仍需注意细节。本文通过使用JMSL 4.0库中的图表对象作为示例,提供了一种实用的方法。 ... [详细]
  • 长期从事ABAP开发工作的专业人士,在面对行业新趋势时,往往需要重新审视自己的发展方向。本文探讨了几位资深专家对ABAP未来走向的看法,以及开发者应如何调整技能以适应新的技术环境。 ... [详细]
  • Beetl是一款先进的Java模板引擎,以其丰富的功能、直观的语法、卓越的性能和易于维护的特点著称。它不仅适用于高响应需求的大型网站,也适合功能复杂的CMS管理系统,提供了一种全新的模板开发体验。 ... [详细]
  • publicclassBindActionextendsActionSupport{privateStringproString;privateStringcitString; ... [详细]
  • JUnit下的测试和suite
    nsitionalENhttp:www.w3.orgTRxhtml1DTDxhtml1-transitional.dtd ... [详细]
  • 一、Advice执行顺序二、Advice在同一个Aspect中三、Advice在不同的Aspect中一、Advice执行顺序如果多个Advice和同一个JointPoint连接& ... [详细]
  • protobuf 使用心得:解析与编码陷阱
    本文记录了一次在广告系统中使用protobuf进行数据交换时遇到的问题及其解决过程。通过这次经历,我们将探讨protobuf的特性和编码机制,帮助开发者避免类似的陷阱。 ... [详细]
  • 本文总结了近年来在实际项目中使用消息中间件的经验和常见问题,旨在为Java初学者和中级开发者提供实用的参考。文章详细介绍了消息中间件在分布式系统中的作用,以及如何通过消息中间件实现高可用性和可扩展性。 ... [详细]
  • Python作为当今IT领域中最受欢迎且高效的语言之一,其框架能够显著加速Web应用程序的开发过程。本文推荐并对比了十大顶级Python Web开发框架,其中CubicWeb以其卓越的代码重用性和模块化设计脱颖而出,为开发者提供了强大的支持。 ... [详细]
  • 当前,众多初创企业对全栈工程师的需求日益增长,但市场中却存在大量所谓的“伪全栈工程师”,尤其是那些仅掌握了Node.js技能的前端开发人员。本文旨在深入探讨全栈工程师在现代技术生态中的真实角色与价值,澄清对这一角色的误解,并强调真正的全栈工程师应具备全面的技术栈和综合解决问题的能力。 ... [详细]
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社区 版权所有