`

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

    博客分类:
  • 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的纯粹与简单。

分享到:
评论

相关推荐

    Java闭包 Java闭包

    JSR-335 将闭包引入了 Java 。闭包在现在的很多流行的语言中都存在,例如 C++、C# 。闭包允许我 们创建函数指针,并把它们作为参数传递。在这篇文章中,将粗略的看一遍Java8的特性,并介绍 Lambda表达式。而且将试...

    什么是闭包?闭包的优缺点?

    什么是闭包?闭包的优缺点?

    Java闭包练习

    在Java 8中,引入了Lambda表达式来简化匿名内部类的使用,从而更好地支持闭包。Lambda表达式可以被视为没有名字的方法,它可以捕获和存储它被定义时所在作用域内的变量值。这使得Lambda能够访问并修改其外部作用域的...

    传递闭包warshall算法java实现

    传递闭包是图论中的一个重要概念,特别是在研究有向图的可达性问题时。Warshall算法是由美国计算机科学家Stephen Warshall于1962年提出的,它主要用于计算有向图的所有节点对之间的传递闭包。在图中,如果存在一条从...

    Java中的闭包与回调.rar

    例如,在Java 8引入的Lambda表达式中,闭包的概念尤为明显。Lambda表达式可以看作是一个没有名字的函数,它可以捕获其周围(也称为词法环境)的变量,并在需要时使用它们。以下是一个简单的示例: ```java public ...

    详解Java的闭包

    Lambda 表达式是 Java 8 引入的一项重要特性,它提供了一种简洁的方式来表示没有名字的函数。Lambda 表达式的语法如下: `(parameters) -> expression` 这里,`parameters` 是输入参数列表,`expression` 是函数体...

    闭包搜索算法java编程

    It is important in distributed computer systems to identify those events (at identifiable points in time) that are concurrent, or not related to each other in time. A group of concurrent events may ...

    山东大学三元闭包实验

    4. 结果可视化:最后,可能还需要将结果可视化,例如绘制网络图,以直观地展示三元闭包关系。 在压缩包中的“三元闭包”文件很可能是包含实验代码的文本文件。代码可能分为几个部分,包括数据输入、闭包算法实现、...

    Java中闭包简单代码示例

    Java中闭包简单代码示例 在 Java 中,闭包是一个非常重要的概念,它允许开发者在函数中捕捉和保存变量的值,从而实现代码的复用和模块化。在本文中,我们将通过一个简单的示例代码,来了解 Java 中闭包的定义和应用...

    python闭包.html

    什么是闭包?如何设置闭包?创建闭包可以用来干什么?闭包的好处,如何正确使用闭包?通过闭包能创建一些只有当前函数能访问的变量,

    js闭包是什么?.pdf

    闭包是JavaScript中的一个核心概念,对于理解函数式编程以及JavaScript中的作用域和变量访问机制至关重要。 闭包(Closure)是函数和声明该函数的词法环境的组合。简单来说,一个闭包允许一个函数访问并操作函数...

    C语言实现三种闭包算法(传递,自反,对称闭包)

    首先,我们需要理解这些闭包的定义: 1. **传递闭包**:在一个关系集合中,如果对于所有的元素a、b和c,只要a与b有关系且b与c有关系,那么a与c也一定有关系,这样的关系被称为传递闭包。在图论中,这相当于寻找最长...

    离散数学的各种闭包运算

    7. **有界面的Java编程**:在实际应用中,我们可能会编写Java程序来实现这些闭包运算,并提供用户界面进行交互。这可能涉及到图形用户界面(GUI)的开发,如Swing或JavaFX,用户可以输入关系矩阵,程序计算并显示...

    Swift 中的闭包和 Objective-C 中的Block

    Swift中的闭包和Objective-C中的Block是两种编程语言中实现匿名函数的关键特性,它们允许我们定义可以在不同上下文中使用的代码块。尽管这两种语言都属于Apple的生态系统,但它们在闭包和Block的概念上有细微差别。 ...

    离散数学-关系,集合,求自反闭包,对称闭包,传递闭包

    离散数学-关系,集合,求自反闭包,对称闭包,传递闭包 离散数学-关系,集合,求自反闭包,对称闭包,传递闭包 离散数学-关系,集合,求自反闭包,对称闭包,传递闭包 离散数学-关系,集合,求自反闭包,对称闭包...

    Recursive:Java 8 的递归闭包

    在Java 8之前,Java不支持真正的闭包,但引入了Lambda表达式后,它实现了类似的功能。闭包是一种可以访问和修改其定义范围内的变量,即使在该作用域外部执行时也是如此。这主要是通过匿名内部类实现的,但在Java 8中...

    Java中的闭包与回调

    闭包是可以包含自由(未绑定)变量的代码块;这些变量不是在这个代码块或者任何全局上下文中定义的,而是在定义代码块的环境中定义。“闭包”一词来源于以下两者的结合:要执行的代码块(由于自由变量的存在,相关...

    关系闭包的计算

    ### 关系闭包的计算 #### 实验背景与目的 在计算机科学与数学领域中,关系闭包是一种重要的概念,特别是在图论与数据库理论中有着广泛的应用。本实验旨在通过编程实践的方式帮助学习者深入理解关系闭包的概念,并...

    计算NFA中ε闭包

    ### 计算NFA中的ε闭包 #### 一、NFA与ε闭包概念介绍 **非确定有限自动机(NFA)**是一种理论计算模型,它扩展了确定有限自动机(DFA)的概念,允许在某些情况下从一个状态出发到达多个状态。在NFA中,存在一种特殊的...

    求闭包 属性集闭包 函数依赖的闭包

    3. 用户输入完毕所有的依赖后,显示“请输入属性集求闭包”的提示,当用户输入1个或者多个属性时,求出对应的闭包。(如,用户输入A,则显示A+的值, 用户输入AB则求出AB+的值。显示完毕后,再次显示“请输入属性集...

Global site tag (gtag.js) - Google Analytics