首先明確閉包的概念:一個代碼段被用來做為方法的參數.
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中用的多的偏模板方法,即邏輯中固定一些流程,初始化及釋放某些資源。
動態回調函數、匿名內部類和spring中的excute方法
public Object get(final Class entityClass, final Serializable id, final LockMode lockMode)