百家争鸣 Java需要引入闭包吗?
创始人
2024-04-02 09:11:00
0

首先先了解一下什么是闭包

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

可能上面的定义有点晦涩,下面看一下《Python 核心编程》对闭包的解释。

如果在一个内部函数里,对在外部作用域(但不是在全局作用域)的变量进行引用,那么内部函数就被定义为闭包 。定义在外部函数内的但由内部函数引用或者使用的变量被称为自由变量 。

下面是一个闭包的例子 (由于Java现在不支持闭包,这个闭包的例子是用Python写的,参见了《Python 核心编程》 )

Python代码

  1. def counter(start_at = 0):     
  2.     count = [start_at]     
  3.     def incr():     
  4.         count[0] += 1    
  5.         return count[0]     
  6.     return incr    
  7.  
  8. def counter(start_at = 0):  
  9.     count = [start_at]  
  10.     def incr():  
  11.         count[0] += 1  
  12.         return count[0]  
  13.     return incr  

这里面count变量 就是一个 相对于函数incr 的自由变量(它在 函数incr 的外部作用域上,但又不在全局作用域上),内部函数incr 可以引用和使用这个变量。这个例子主要模拟一个计数器。

运行下面的代码

Java代码

  1. count = counter(6)     
  2. print count()     
  3. print count()    
  4.  
  5. count = counter(6)  
  6. print count()  
  7. print count()  

就会打印出

    7

    8

我们发现 内部函数(incr)不但可以引用其自身定义的变量,还可以引用外部函数(counter)定义的变量。或者说 内部函数(闭包) 可以记忆状态, 它可以根据 它记忆的状态 来执行不同的操作。 而外部函数负责初始化状态(内部函数需要记忆的状态)。

那么为什么需要闭包,闭包的优势是什么呢?我觉得就是可以记忆状态,但对象也可以记忆状态(通过对象的属性)。那闭包和对象的区别是什么呢? 我觉得就因为闭包是函数而不是对象。我们会发现,如果用面向对象的方式来表达闭包内部函数(闭包)就像 对象的方法而外部函数  对象的构造器。构造器用来初始化对象状态而对象的方法可以根据 对象的状态 来执行不同的操作。

好!下面我们用面向对象的方式 创建一个 计数器(实现和上例一样的功能,用Java实现)。

Java代码

  1. public class Counter {     
  2.     private int startAt;     
  3.     public Counter() {     
  4.         this(0);     
  5.     }     
  6.     public Counter(int startAt) {     
  7.         this.startAt = startAt;     
  8.     }     
  9.     public int incr(){     
  10.         return ++ this.startAt;     
  11.     }     
  12. }    
  13.  
  14. public class Counter {  
  15.  private int startAt;  
  16.  public Counter() {  
  17.   this(0);  
  18.  }  
  19.  public Counter(int startAt) {  
  20.   this.startAt = startAt;  
  21.  }  
  22.  public int incr(){  
  23.   return ++ this.startAt;  
  24.  }  

运行Test类

Java代码

  1. public class Test{     
  2.     public static void main(String[] args){     
  3.         Counter counter = new Counter(6);     
  4.         System.out.println(counter.incr());     
  5.         System.out.println(counter.incr());     
  6.     }     
  7. }    
  8.  
  9. public class Test{  
  10.  public static void main(String[] args){  
  11.   Counter counter = new Counter(6);  
  12.   System.out.println(counter.incr());  
  13.   System.out.println(counter.incr());  
  14.  }  
  15. }  

会打印出(和上例打印输出相同)

    7

    8

那么Java(有了对象)还需要引入闭包吗?我觉得不需要,因为对象完全可以模拟闭包的行为,而且对象才是OOP 的一级元素。闭包是函数式编程(FP)中的概念,引入闭包就相当于引入FP,这只会破坏Java的纯粹与简单。

【编辑推荐】

  1. Java虚拟机几个命令行参数说明
  2. Java虚拟机发展回顾 为跨平台而生
  3. Java虚拟机概念及体系结构
  4. 在Netbeans上安装JavaFX插件
  5. JavaBean中使用JDBC连接进行事务处理

相关内容

热门资讯

如何允许远程连接到MySQL数... [[277004]]【51CTO.com快译】默认情况下,MySQL服务器仅侦听来自localhos...
如何利用交换机和端口设置来管理... 在网络管理中,总是有些人让管理员头疼。下面我们就将介绍一下一个网管员利用交换机以及端口设置等来进行D...
施耐德电气数据中心整体解决方案... 近日,全球能效管理专家施耐德电气正式启动大型体验活动“能效中国行——2012卡车巡展”,作为该活动的...
20个非常棒的扁平设计免费资源 Apple设备的平面图标PSD免费平板UI 平板UI套件24平图标Freen平板UI套件PSD径向平...
德国电信门户网站可实时显示全球... 德国电信周三推出一个门户网站,直观地实时提供其安装在全球各地的传感器网络检测到的网络攻击状况。该网站...
为啥国人偏爱 Mybatis,... 关于 SQL 和 ORM 的争论,永远都不会终止,我也一直在思考这个问题。昨天又跟群里的小伙伴进行...
《非诚勿扰》红人闫凤娇被曝厕所... 【51CTO.com 综合消息360安全专家提醒说,“闫凤娇”、“非诚勿扰”已经被黑客盯上成为了“木...
2012年第四季度互联网状况报... [[71653]]  北京时间4月25日消息,据国外媒体报道,全球知名的云平台公司Akamai Te...