百家争鸣 Java需要引入闭包吗?

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

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

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

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

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

 

def counter(start_at = 0):     
    count = [start_at]     
    def incr():     
        count[0] += 1    
        return count[0]     
    return incr    
 
def counter(start_at = 0):  
    count = [start_at]  
     def incr():  
         count[0] += 1  
         return count[0]  
     return incr  

 

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

运行下面的代码

Java代码

14 count = counter(6)     

15 print count()     

16 print count()    

17  

18 count = counter(6)  

19 print count()  

20 print count()  

就会打印出

7

8

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

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

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

public class Counter {     
    private int startAt;     
    public Counter() {     
        this(0);     
    }     
    public Counter(int startAt) {     
        this.startAt = startAt;     
    }     
    public int incr(){     
        return ++ this.startAt;     
    }     
}    
 
public class Counter {  
 private int startAt;  
 public Counter() {  
  this(0);  
 }  
 public Counter(int startAt) {  
  this.startAt = startAt;  
 }  
 public int incr(){  
  return ++ this.startAt;  
 }  
} 

 

 

运行Test

public class Test{     
    public static void main(String[] args){     
        Counter counter = new Counter(6);     
        System.out.println(counter.incr());     
        System.out.println(counter.incr());     
    }     
}    
 
public class Test{  
 public static void main(String[] args){  
  Counter counter = new Counter(6);  
  System.out.println(counter.incr());  
  System.out.println(counter.incr());  
 }  
}  

 

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

7

8

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

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值