Java 7的第一类函数:学习闭包的使用

本文来自Liuu的博客,原文标题为《Java7准备让函数成为一等公民》。

如果你是一个Java程序员,你认识“#”么?让我猜猜看,应该不太熟吧。因为在Java1.4.2时代,“#”仅仅用于在编写javadoc的注释内容,用于链接(@see)到对应类的具体方法。除此之外,在编写代码的时候,我们几乎不会用到它。

编辑推荐:Java 7,下一代Java开发技术详解

不过,别惊讶,在Java 7发布之后,“#”或许将成为Java程序员最熟悉的朋友!因为在几天前(编辑注:本文翻译于09年11月底,当时Sun刚刚公布说Java 7将包含简单的闭包),Sun的Java SE和OpenJDK的首席工程师Mark Reinhold,刚刚宣布Java 7将加入一个简化版的“闭包”特性,其中的关键符号,就是“#”。也因为这个原因,Java 7的正式发布时间,将从2010年2月份,推迟到9月份。

在Java 7中,“#”将让函数方法,成为Java语言的一等公民。下面来看看如何用#语法实现“闭包”的吧:

简单的方法引用示例:

比如要引用String类的equals方法,应该这么写:

 
 
 
  1. String#equals(Object)  

再看一个例子:

 
 
 
  1. java.io.File#exists()   

事件监听器1 (代码示例,来自Cay Horstmann)

使用闭包前:

 
 
 
  1. button.addActionListener(   
  2. new ActionListener() {  
  3.  public void actionPerformed(ActionEvent ){  
  4. System.out.println("Hi!"); }   
  5.  }   
  6. );  
  7.  

使用闭包后 :

 
 
 
  1. button.addActionListener(#(ActionEvent e) System.out.println("Hi!));  
  2.  

事件监听器2(代码示例,来自FSM )

使用闭包前:

 
 
 
  1. public void init() {  
  2. JButton button = ...;  
  3. button.addActionListener(new ActionListener() {  
  4.  public void actionPerformed(ActionEvent ev) {  
  5.  handleAction(ev);  
  6.  }  
  7. });  
  8. }  
  9. public void handleAction(ActionEvent ev) {  
  10. // handle event  
  11. }  
  12.  

使用闭包后:

 
 
 
  1. public void init() {  
  2. JButton button = ...;  
  3. button.addActionListener(this#handleAction(ActionEvent));  
  4. }  
  5. public void handleAction(ActionEvent ev) {  
  6. // handle event  
  7. }  
  8.  

排序比较器(代码示例,来自FSM 、Cay Horstmann)

使用闭包前:

 
 
 
  1. List<String> list = ...  
  2. Collections.sort(list, new Comparator<String>() {  
  3. public int compare(String str1, String str2) {  
  4.  return str1.length() - str2.length();  
  5. }  
  6. });  
  7.  

使用闭包后:

 
 
 
  1.  List<String> list = ...  
  2. Collections.sort(list, #(String str1, String str2) {  
  3. return str1.length() - str2.length();  
  4. });  
  5.  

甚至或简化成:

 
 
 
  1. Collections.sort(strings,   
  2. #(String a, String b) a.length() - b.length());   
  3.  

最后,我们复习一下javadoc中的#的用法:

引用当前类的成员字段、方法、构造器

 
 
 
  1. @see#field  
  2.  
  3. @see#method(Type, Type,...)  
  4.  
  5. @see#method(Type argname, Type argname,...)  
  6.  
  7. @see#constructor(Type, Type,...)  
  8.  
  9. @see#constructor(Type argname, Type argname,...)  
  10.  

引用已经导入的类的成员字段、方法、构造器,或嵌套类

 
 
 
  1. @seeClass#field  
  2.  
  3. @seeClass#method(Type, Type,...)  
  4.  
  5. @seeClass#method(Type argname, Type argname,...)  
  6.  
  7. @seeClass#constructor(Type, Type,...)  
  8.  
  9. @seeClass#constructor(Type argname, Type argname,...)  
  10.  
  11. @seeClass.NestedClass  
  12.  
  13. @seeClass 
  14.  

引用其他包里的类成员

 
 
 
  1. @seepackage.Class#field  
  2.  
  3. @seepackage.Class#method(Type, Type,...)  
  4.  
  5. @seepackage.Class#method(Type argname, Type argname,...)  
  6.  
  7. @seepackage.Class#constructor(Type, Type,...)  
  8.  
  9. @seepackage.Class#constructor(Type argname, Type argname,...)  
  10.  
  11. @seepackage.Class.NestedClass  
  12.  
  13. @seepackage.Class  
  14.  
  15. @seepackage   
  16.  

#t#以前曾经翻译过一篇文章离开Java,寻找更佳语言的10大理由(更新),现在看来Java或许已经听到了太多这样的声音。因此,在Java 7中,里面提到的大部分问题都得到了改进,甚至包括现在突然宣布要加入的闭包,并让函数成为一等公民。这应该是一件好事,只是,有个小小的疑惑,Java似乎越来越像Ruby这样的动态语言了,Java 7还会是我们熟悉的Java么?

THE END