论坛首页 Java企业应用论坛

JAVA 需要引入闭包吗

浏览 38519 次
该帖已经被评为精华帖
作者 正文
   发表时间:2009-06-10   最后修改:2009-06-11
OO

最近有很多人 呼吁 要在JAVA的新版本中引入闭包。

那么JAVA 或者说 OOPL (面向对象编程语言)需要引入闭包吗,有了对象还需要闭包吗?

 

收先先了解一下什么是闭包,


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

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

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

 

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

 

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

 

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

运行下面的代码

 

count = counter(6)
print count()
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;
	}
}

 

 

 运行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());
	}
}

 

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

 

    7

    8

 

 

那么JAVA(有了对象)还需要引入闭包吗?

我觉得不需要,

因为对象完全可以模拟 闭包 的行为,

而且 对象 才是 OOP 的 一级元素。

闭包 是 函数式编程(FP) 中的 概念,

 引入闭包 就相当于 引入 FP,

这只会破坏 JAVA 的 纯粹 与 简单 。。

 

 

 

 

   发表时间:2009-06-10  
好像 JAVA 在新版本中 没有引入闭包
因为 引入闭包 这项工作太复杂
0 请登录后投票
   发表时间:2009-06-10  
不太懂闭包
不过看懂了你这个python的例子,挺简单的
有点像对象
闭包就这么简单吗,有没有什么经典应用
0 请登录后投票
   发表时间:2009-06-10  
visitor 写道
好像 JAVA 在新版本中 没有引入闭包
因为 引入闭包 这项工作太复杂

好像是这样 , 反正我觉得没必要 呵呵
0 请登录后投票
   发表时间:2009-06-11  
不要..
已经有动态语言了,不要再对java做这种变化,更灵活更复杂,底下程序员又要叫唤了..
2 请登录后投票
   发表时间:2009-06-11  
如果一种语言最开始没有考虑到闭包的话不太好弄闭包的,其实python的闭包也很弱的
0 请登录后投票
   发表时间:2009-06-11  
function getX(){
    var x;
    callAMethod(function(){
         x = 5*10;
    });
    return x;
}

而对于 Java 只能这么写
public int getX(){
    final int[] x = new int[1];
    callAMethod(new OneCallback(){
        public void aInterfaceMethod(){
           x[0] = 5*10;
        }
    });
    return x[0];
}


才有可能定义一个通用的 Callback 接口,麻烦一点
0 请登录后投票
   发表时间:2009-06-11  
zozoh 写道
function getX(){
    var x;
    callAMethod(function(){
         x = 5*10;
    });
    return x;
}

而对于 Java 只能这么写
public int getX(){
    final int[] x = new int[1];
    callAMethod(new OneCallback(){
        public void aInterfaceMethod(){
           x[0] = 5*10;
        }
    });
    return x[0];
}


才有可能定义一个通用的 Callback 接口,麻烦一点


用内部类来模拟闭包确实麻烦一些
因为函数不是JAVA的一级元素

不过非要用闭包来实现一些功能吗?
我觉得用OO的方式完全可以实现。。
0 请登录后投票
   发表时间:2009-06-11  
要闭包!!!
0 请登录后投票
   发表时间:2009-06-11  














  • 大小: 13.1 KB
  • 大小: 4.5 KB
  • 大小: 6.1 KB
  • 大小: 11.6 KB
0 请登录后投票
论坛首页 Java企业应用版

跳转论坛:
Global site tag (gtag.js) - Google Analytics