`
步行者
  • 浏览: 169832 次
  • 性别: Icon_minigender_1
  • 来自: 武汉
社区版块
存档分类
最新评论

JAVA 需要引入闭包吗

    博客分类:
  • JAVA
阅读更多

最近有很多人 呼吁 要在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 的 纯粹 与 简单 。。

 

 

 

 

分享到:
评论
53 楼 evabibi 2009-06-11  
步行者 写道
WhisperXD 写道
步行者 写道
WhisperXD 写道
太懒 不想为了解决一个方法学两种或多种实现。

我想这足够block这个需求了。除非做不到。


一个方法学 如果有多种实现 ,那也是符合这个方法学的

OO实现中 引入闭包 就需要做一个思维转换,对象 函数化


我是说不想学。

不是方法学,你可能看错了。

我对用什么方法解决问题并不关心。

我关心的是如何解决问题

如果能解决问题,那我关心的是如何成本最低。

包括学习成本在内都是考虑的因素。

包括其他人看代码以后的学习成本,如果一个代码已经被无数人描述为精妙到很难理解,那么除非它有不可替代的作用,否则就是垃圾一堆。

语言只是工具,工具的作用是什么不需我重复了,高效低成本解决问题就行了。



呵呵 看错了

不过只有实现 和 设计契合,才能有更高可维护性
确实 我现在就要怀疑一下 闭包 有没有什么不可替代的作用



没有什么东西是不可替代的 .

只有更好的方法.和更多的选择.




闭包可以减少很多代码量和无用逻辑.

也符合oo的规范.



52 楼 night_stalker 2009-06-11  
fixnum 有可能降低 benmark 评分呢。

bytecode 层面 tailcall 伤筋动骨,估计没戏吧。
51 楼 幸存者 2009-06-11  
RednaxelaFX 写道
赶紧把tailcall和fixnum这些给加上更有用一些。

说实话我也不理解为什么java和c#到现在都不支持尾递归优化。
50 楼 步行者 2009-06-11  
RednaxelaFX 写道
闭包和对象本是同根生……

‘根’是哪呢
既然有了‘对象’为什么又把兄弟‘闭包’拉进来呢
这个‘闭包’兄弟  到底有什么杀手锏(‘对象’不能做) ?
49 楼 RednaxelaFX 2009-06-11  
闭包和对象本是同根生……(传送门1
“继承/封装/多态”那要说也只能算是Java对象的特征,并不意味着别的对象系统也一样。

“Java最初不要闭包是为了保持语言的简单,是为程序员着想” << 没那回事啦。Bill Joy一早就说要闭包,结果跟James Gosling他们闹翻了,因为Gosling他们市场目的性更强,要赶工把半成品推出去(传送门2)。总不能跟人家说我们没实现某功能是因为赶工来不及吧,干脆美其名曰要保持语言的简单。不然后来也不会想到加入匿名内部类。

Java里不是一切都是对象,方法不是对象,基本类型也不是。Gosling说这是为了效率考虑,但从现在那么多类似的系统看来,Gosling的效率说更像是个人风格而已。所以说Java是“纯面向对象语言”……它确实只能很好的支持面向对象范型,但并不是完整的支持了这范型,是种“纯纯的残缺美”。注意了,“残缺”在这里不是贬义修饰,而是一种个性的体现。附带的好处是概念比较少,不用学那么多(不考虑装拆箱之类的问题的话)

至于现在的Java要不要加入闭包呢?BGGA方案功能强大但是看起来还是有点怪。Neal Gafter跳到微软去了之后还在继续推动BGGA方案的宣传,辛苦了。FCM看起来正常些,如果要加的话我会倾向FCM。不加也罢,赶紧把tailcall和fixnum这些给加上更有用一些。
48 楼 simon511 2009-06-11  
java 不支持闭包,不过它可以用匿名的内部类来实现闭包,当然实现的代码让人看起来不是很舒服。
引入闭包,确实可以让代码简洁不少,让程序员可以省去一些额外附加代码。
至于会不会破坏java的结构? 就目前来看很多面向对象的语言(python ruby groovy C#)都已经有了,也听说这些语言有了闭包,而影响了什么.
语言就是一种工具,好不好看是次要的,重要的是好用.
47 楼 night_stalker 2009-06-11  
akunspy 写道
忍不住说句.
OO不是银弹.
做开发多年,最大的收获之一是放下了OO包袱.
KISS才是最高准则.


Runnable 这些魔法词汇是学习成本非常高的,不过一些打拼过来的老同志们都觉得理所当然了,不想改了,痛苦的学习经验也会让他们非常抵触一些新特性,就算能减轻劳动强度,他们都不愿意。

给两个链接。不喜 haskell 勿入……
Haskell 类型系统 http://haskell.org/haskellwiki/Simonpj/Talk:FunWithTypeFuns
如何放弃 OOP http://night-stalker.iteye.com/blog/381756


话说世界上几乎 100% 的程序员都用过闭包了,也无所谓学习成本了。
javascript 的函数都是闭包呢……

另外还有就是 Tiobe 前十,就剩 Java 不支持闭包吧。迟早都会支持的。(在前不久 Apple 公布的 GCD 里面,连 C 都可以用闭包了)
46 楼 步行者 2009-06-11  
pancras 写道
我觉得需要引入,多一种方法有什么不好,觉得不好用的同学可以不用好了。没有这个功能想用也用不了,有了这个功能,想用就用,不想用可以不用。


呵呵 不过引入后 用可能对JAVA的结构产生影响
而且 如果一些有用的API用到了闭包,
那么你不想用也得用了
45 楼 pancras 2009-06-11  
我觉得需要引入,多一种方法有什么不好,觉得不好用的同学可以不用好了。没有这个功能想用也用不了,有了这个功能,想用就用,不想用可以不用。
44 楼 步行者 2009-06-11  
WhisperXD 写道
步行者 写道
WhisperXD 写道
太懒 不想为了解决一个方法学两种或多种实现。

我想这足够block这个需求了。除非做不到。


一个方法学 如果有多种实现 ,那也是符合这个方法学的

OO实现中 引入闭包 就需要做一个思维转换,对象 函数化


我是说不想学。

不是方法学,你可能看错了。

我对用什么方法解决问题并不关心。

我关心的是如何解决问题

如果能解决问题,那我关心的是如何成本最低。

包括学习成本在内都是考虑的因素。

包括其他人看代码以后的学习成本,如果一个代码已经被无数人描述为精妙到很难理解,那么除非它有不可替代的作用,否则就是垃圾一堆。

语言只是工具,工具的作用是什么不需我重复了,高效低成本解决问题就行了。



呵呵 看错了

不过只有实现 和 设计契合,才能有更高可维护性
确实 我现在就要怀疑一下 闭包 有没有什么不可替代的作用

43 楼 WhisperXD 2009-06-11  
步行者 写道
WhisperXD 写道
太懒 不想为了解决一个方法学两种或多种实现。

我想这足够block这个需求了。除非做不到。


一个方法学 如果有多种实现 ,那也是符合这个方法学的

OO实现中 引入闭包 就需要做一个思维转换,对象 函数化


我是说不想学。

不是方法学,你可能看错了。

我对用什么方法解决问题并不关心。

我关心的是如何解决问题

如果能解决问题,那我关心的是如何成本最低。

包括学习成本在内都是考虑的因素。

包括其他人看代码以后的学习成本,如果一个代码已经被无数人描述为精妙到很难理解,那么除非它有不可替代的作用,否则就是垃圾一堆。

语言只是工具,工具的作用是什么不需我重复了,高效低成本解决问题就行了。
42 楼 303535576 2009-06-11  
akunspy 写道
忍不住说句.
OO不是银弹.
做开发多年,最大的收获之一是放下了OO包袱.
KISS才是最高准则.


KISS??? 请指点一下
什么是KISS
41 楼 WhisperXD 2009-06-11  
akunspy 写道
忍不住说句.
OO不是银弹.
做开发多年,最大的收获之一是放下了OO包袱.
KISS才是最高准则.


我觉得这才像oo.呵呵

记住封装变化这个本质,其余的都可放下。
40 楼 akunspy 2009-06-11  
忍不住说句.
OO不是银弹.
做开发多年,最大的收获之一是放下了OO包袱.
KISS才是最高准则.
39 楼 步行者 2009-06-11  
icefishc 写道
步行者 写道
bookong 写道
如果真引入闭包,写代码是少了,恐怕调试会更痛苦一点。

不光这些
1,函数做为一级元素,不光要import类了,还要import函数
或者 就像 python一样 要把 文件粒度改为 module了
2,那JAVA中的一切皆对象,就要被打破了

为什么 调试会痛苦一些?
如果函数也是对象 那么不久符合一切皆对象的了么。


我觉得 闭包更像对象方法
而不是对象
38 楼 步行者 2009-06-11  
WhisperXD 写道
太懒 不想为了解决一个方法学两种或多种实现。

我想这足够block这个需求了。除非做不到。


一个方法学 如果有多种实现 ,那也是符合这个方法学的

OO实现中 引入闭包 就需要做一个思维转换,对象 函数化
37 楼 WhisperXD 2009-06-11  
icefishc 写道
WhisperXD 写道
太懒 不想为了解决一个方法学两种或多种实现。

我想这足够block这个需求了。除非做不到。

那你为什么用Java没有它不也什么都能做么


因为java流行

长时间排名第一

我就是如此势力,哈哈

36 楼 visitor 2009-06-11  
night_stalker 写道
步行者 写道
night_stalker 写道
步行者 写道
不光要import类了,还要import函数


??


因为 类 和 函数 是同等级别的了


函数和对象同级, 函数类型和类同级。 不需要 import 函数。

不import进来 你怎么引用 函数
35 楼 icefishc 2009-06-11  
WhisperXD 写道
太懒 不想为了解决一个方法学两种或多种实现。

我想这足够block这个需求了。除非做不到。

那你为什么用Java没有它不也什么都能做么
34 楼 visitor 2009-06-11  
icefishc 写道
步行者 写道
bookong 写道
如果真引入闭包,写代码是少了,恐怕调试会更痛苦一点。

不光这些
1,函数做为一级元素,不光要import类了,还要import函数
或者 就像 python一样 要把 文件粒度改为 module了
2,那JAVA中的一切皆对象,就要被打破了

为什么 调试会痛苦一些?
如果函数也是对象 那么不久符合一切皆对象的了么。


因为混乱 所以 可能产生痛苦

有一种观点认为 闭包 就是 函数对象
因为闭包已经不是单纯的函数了(它记忆了外部状态)

但它也不符合对象的规范,不能继承,重载,覆盖。。。

相关推荐

    Java闭包 Java闭包

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

    Java闭包练习

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

    Java中的闭包与回调.rar

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

    详解Java的闭包

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

    Recursive:Java 8 的递归闭包

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

    跨越边界:闭包

    闭包是一种强大的编程概念,它允许函数访问和操作其外部作用域中的变量,即使在函数执行完毕后仍然...因此,对于是否应该在编程语言中引入闭包,取决于开发者对复杂性与功能性的权衡,以及对语言设计理念的理解和偏好。

    Java中使用Groovy的三种方式

    Java 6引入了JSR 223(Scripting for the Java Platform),允许在Java程序中直接执行脚本语言。Groovy可以作为这种嵌入式脚本语言使用。通过`groovy.lang.GroovyShell`或`groovy.lang.GroovyScriptEngine`,你可以...

    Java in easy steps Covers Java 9 6th Edition

    Java是一种广泛使用的面向对象编程语言,它从Java 8版本开始引入了Lambda表达式和流(Streams),从而增强了Java的函数式编程特性。《Java in easy steps》涵盖了Java 9,并特别针对Java 8的新特性进行了详细讲解。...

    java入门笔记.pdf

    文档还介绍了设计模式,如单例模式,以及Java中的闭包、内部类、异常处理、抽象类与接口等高级特性。 ### Java多线程 Java多线程部分详细解释了如何创建和管理线程、线程池的使用、volatile关键字、死锁、线程通信...

    Java 8 Nashorn 脚本引擎

    Nashorn引擎首次引入于Java 8,作为对之前Rhino JavaScript引擎的升级,旨在提供更快的速度和更现代的JS语法支持。 Nashorn引擎的主要特性包括: 1. **高性能**:Nashorn比Rhino更快,因为它基于Java的HotSpot...

    OnJava8-Examples-master.zip

    7. **函数式编程概念**:Java 8鼓励函数式编程风格,如使用高阶函数和闭包。这些特性使得Java更适合并行处理和大数据处理场景。 8. **并行流(Parallel Stream)**:Java 8的Stream API支持并行流,可以自动利用多核...

    JAVA JAVA JAVA JAVA

    - **闭包**:闭包允许函数访问和修改其外部词法作用域的变量,即使在其外部函数已经执行完毕后。 - **异步编程**:JavaScript通过回调函数、Promise和async/await来处理异步操作,如Ajax请求和定时器。 - **DOM操作*...

    Java SE 8的55个新特性

    这使得Java支持了闭包和函数式编程的概念。Lambda表达式为Java提供了匿名函数类型,可以用来简化接口的实现,并在函数式接口上使用,极大地提高了编程的灵活性和效率。 另外,Java SE 8通过扩展方法(也称为默认...

    Functional Interfaces in Java.pdf

    近年来,随着函数式编程概念的普及和Java 8的发布,Java引入了“函数式接口”的概念,给Java的接口设计带来了全新的变革。函数式接口是指那些只定义了一个抽象方法的接口,允许通过lambda表达式来实现更简洁的代码,...

    beyond java

    5. **闭包和块**:Ruby的块和闭包是强大的功能,允许在函数内部定义局部作用域的代码块,可作为参数传递,这在Java 8之后才引入类似的概念(Lambda表达式)。 6. **并发模型**:Java使用线程进行并发处理,而Ruby...

    java html 所有帮助文档

    Java帮助文档,通常被称为Java API文档,包含了Java平台标准版(Java SE)、企业版(Java EE)和微服务版(Java ME)的所有类、接口、方法和异常的详细信息。这些文档是开发者日常编码时的重要参考资料,能够帮助...

    java语言的发展

    Java7于2010年9月预览,2011年7月正式发布,引入了闭包等新特性,增强了语言的表达能力和并发处理能力。这些更新展示了Java持续创新和适应技术变革的决心。 Java的发展历程充分体现了其适应性和灵活性,从最初的...

    java lambda入门到高级代码实例

    Java Lambda 是一种强大的语法特性,它在 Java 8 中被引入,使得函数式编程成为可能。Lambda 表达式简化了处理匿名函数的方式,让代码更简洁、易读。在这个"java lambda入门到高级代码实例"中,我们将深入探讨Lambda...

    Java Groovy

    - **兼容性**:Groovy不仅支持Java类库,还能直接调用Java代码,这为开发者提供了一种在不改变现有Java环境的情况下引入新特性的途径。 - **灵活性**:Groovy支持元编程系统(MPS)和运行时注入(RTI),使得...

Global site tag (gtag.js) - Google Analytics