首先明确闭包的概念:一个代码段被用来做为方法的参数.
java中没有直接使用某个方法做为另一个方法的参数的,java使用匿名内部类来模拟这种情况。
匿名内部类往往是做为一个内部类(接口)的具体实现。在一些平台类(platform class)中有一些模板方法。模板方法的包含了固定流程。其中某些步骤是调用了内部类(接口)中的某些方法。但是平台类将这些方法的具体实现延迟到了业务类中。业务类调用平台类的模板方法,但是传入匿名内部类的实现做为模板方法的参数。
示例:
package callback;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
public class AnonymousBusinessTemplateExample2 {
// 内部接口也是回调接口,只定义抽象方法。
private interface Callback {
Object doIt(Connection conn) throws SQLException;
}
// 模板方法(抽象)
private Object execute(Callback callback) throws SQLException {
Connection conn = openConnection();
try {
return callback.doIt(conn);
} finally {
closeConnection(conn);
}
}
// 业务方法(具体)
public Object sqlQuery(final String sql) throws SQLException {
//匿名内部类做为模板方法的参数来模拟闭包
return execute(new Callback() {
public Object doIt(Connection conn) throws SQLException {
return conn.createStatement().executeQuery(sql);
}
});
}
public Connection openConnection() throws SQLException {
return DriverManager.getConnection("", null);
}
public void closeConnection(Connection conn) throws SQLException {
if (conn != null && !conn.isClosed()) {
conn.close();
}
}
}
一般内部接口比内部类用的更多。内部类中的方法可以有默认的实现。匿名内部类做为业务方法的参数传入时,会override默认的方法。内部接口的话,没有默认的实现。完全将具体的实现交给了匿名内部类。
匿名内部类的思想是回调,即好茉坞原则。回调的一个好处是decouple。 客户端只需要关心业务(比如匿名内部类的具体实现)而不用再关心一些资源的连接释放什么的,这些交给平台类中的模板方法。ruby的闭包还支持对数组中的每个元素,文件中的每行,结果集中的每个记录的操作。而用java实现这样的迭代并操作其中元素非常麻烦。感觉java中用的多的偏模板方法,即逻辑中固定一些流程,初始化及释放某些资源。
推荐:http://www.ibm.com/developerworks/cn/java/j-cb01097.html