论坛首页 Java企业应用论坛

初探Java8新特性之lambda表达式

浏览 24341 次
精华帖 (0) :: 良好帖 (0) :: 新手帖 (0) :: 隐藏帖 (0)
作者 正文
   发表时间:2012-11-27  
nkadun 写道
搞球搞啊就搞球成动态语言了……正在下决心转c中……

童鞋  这不能算是动态吧?? C也有匿名函数的,有函数指针,可一点也不比这个简单哦
0 请登录后投票
   发表时间:2012-11-27  
hypercube1024 写道
自动进行回调接口的类型推断,相当不错:-)

不仅如此,其实()内的变量的类型也可以不写的,比如例子中的
Comparator<String> c = (s1, s2) -> s1.compareToIgnoreCase(s2);
s1,s2的类型都是能推断出来是String  确实方便了不少
0 请登录后投票
   发表时间:2012-11-27  
287854442 写道
hantsy 写道
这还是 Java 吗? Scala 都看得我头晕。

其实要是喜欢这种语言,完全可以由第三方 JVM 语言来担当,Java 核心搞这么复杂干嘛。


我也是啊  Scala的语法太多 受不了
这部分其实也没那么麻烦了 而且如果不想用就可以不用啊  直接内部类也行   lambda可以看到是语法糖嘛,就比如i++和i=i+1一样 想用那个用哪个了

而且其实我觉得lambda表达式 肯定不是内部类的语法糖,我个人认为内部类的效率不会太高,Java8应该是在字节码上支持匿名函数的,而不是像scala一样,纯粹的语法糖,看似是匿名函数,其实后面还是给你生成了一个匿名内部类的实例


按我半年前看那份草案,那基本上就是匿名内部类的语法糖。楼主有没有检查过现在java8里的lambda编译后有没有偷偷摸摸的给你生成一个匿名内部类的class文件。如果没有,那又是一大进步了,给scala解决了一大难题呀。Scala也是没办法,现在的jvm只能通过匿名内部类来实现闭包,它不照着干,就没法和Java无缝整合了,这可是Scala的大卖点之一。
0 请登录后投票
   发表时间:2012-11-28  
目前这种看起来就是语法糖,还是要看编译后的字节码有什么变化

0 请登录后投票
   发表时间:2012-11-28   最后修改:2012-11-28
简单把玩了一下,还不错

函数接口:



测试代码:



注意自由变量c不是final /* 补充,虽然不用声明final,但也不能修改,看楼下 */,编译后生产接口和测试代码两个class文件,不会产生额外的匿名类class了

执行结果





测试代码的bytecode如下

上半身:




下半身:



  • 大小: 3.8 KB
  • 大小: 11.2 KB
  • 大小: 37.9 KB
  • 大小: 28.8 KB
  • 大小: 5.6 KB
0 请登录后投票
   发表时间:2012-11-28  
唯一不爽的地方,似乎没有duck typing。还是要为各种函数接口写Adapter。
0 请登录后投票
   发表时间:2012-11-28  
呃。。。上当受骗了。。。

lambda外部不能改:



lambda内部也不能改:





在lambda函数中引用了外部的局部变量,在初始化后只要发生了更改编译器就不让你通过,事实上就是只能引用final。
  • 大小: 4.4 KB
  • 大小: 3.9 KB
0 请登录后投票
   发表时间:2012-11-28  
kidneyball 写道
呃。。。上当受骗了。。。

lambda外部不能改:



lambda内部也不能改:





在lambda函数中引用了外部的局部变量,在初始化后只要发生了更改编译器就不让你通过,事实上就是只能引用final。


从 重构 那本书上的角度讲,这种写法是不推荐,所有方法参数都应该是可以用 Final 的。
方法中field另外定义,int d =c;

0 请登录后投票
   发表时间:2012-11-28   最后修改:2012-11-28
hantsy 写道
kidneyball 写道
呃。。。上当受骗了。。。

lambda外部不能改:



lambda内部也不能改:





在lambda函数中引用了外部的局部变量,在初始化后只要发生了更改编译器就不让你通过,事实上就是只能引用final。


从 重构 那本书上的角度讲,这种写法是不推荐,所有方法参数都应该是可以用 Final 的。
方法中field另外定义,int d =c;



重点不是应不应该改变形式参数的值,而是java的lambda只要引用了外部局部变量(参数本质上也是局部变量),这个局部变量就不能改,那实质和java 8之前的匿名内部类只能引用final的局部变量是一回事。如果匿名内部类我还可以用内部类的对象属性来模拟真正lambda里的自由变量(虽然写法颇丑)。但java 8的lambda连对象属性都没有,也就是根本不可能有独立的自由变量了,要实现自由变量效果,只能使用匿名内部类,或者把变量挂到外部的对象上作为field,然后把整个外部对象(连带它上面的所有field)作为lambda的闭包了。

P.S. 同理,你这里写了int d = c,一旦在lambda内部引用了d,d也不能改了。



  • 大小: 4.7 KB
0 请登录后投票
   发表时间:2012-11-29  
kidneyball 写道
287854442 写道
hantsy 写道
这还是 Java 吗? Scala 都看得我头晕。

其实要是喜欢这种语言,完全可以由第三方 JVM 语言来担当,Java 核心搞这么复杂干嘛。


我也是啊  Scala的语法太多 受不了
这部分其实也没那么麻烦了 而且如果不想用就可以不用啊  直接内部类也行   lambda可以看到是语法糖嘛,就比如i++和i=i+1一样 想用那个用哪个了

而且其实我觉得lambda表达式 肯定不是内部类的语法糖,我个人认为内部类的效率不会太高,Java8应该是在字节码上支持匿名函数的,而不是像scala一样,纯粹的语法糖,看似是匿名函数,其实后面还是给你生成了一个匿名内部类的实例


按我半年前看那份草案,那基本上就是匿名内部类的语法糖。楼主有没有检查过现在java8里的lambda编译后有没有偷偷摸摸的给你生成一个匿名内部类的class文件。如果没有,那又是一大进步了,给scala解决了一大难题呀。Scala也是没办法,现在的jvm只能通过匿名内部类来实现闭包,它不照着干,就没法和Java无缝整合了,这可是Scala的大卖点之一。



没有生成匿名内部类的class文件,要真是那样,还不如用scala了,不过也比之前生成了很多乱乱的字节码,回头再开个帖子讨论一下Java8的lambda表达式的实现
0 请登录后投票
论坛首页 Java企业应用版

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