回调函数的定义与应用

回调函数的起源还要从C++说起,让我们先来看看C++中是如何使用回调函数的。

回调函数就是一个通过函数指针调用的函数。如果你把函数的指针(地址)作为参数传递给另一个函数,当这个指针被用为调用它所指向的函数时,我们就说这是回调函数。

程序员B要让A调用自己的程序B中的一个方法,于是,他通过A中的接口回调自己B中的方法。

为什么要使用回调函数?

因为可以把调用者与被调用者分开。调用者不关心谁是被调用者,所有它需知道的,只是存在一个具有某种特定原型、某些限制条件(如返回值为int)的被调用函数。

举例

#include<stdio.h>
 
// 方法指针的格式为:int (*ptr)(char *p) 即:返回值(指针名)(参数列表)
typedef int (*CallBackFun)(char *p);  // 为回调函数命名,类型命名为 CallBackFun,参数为char *p
 
int Afun(char *p) {    // 方法 Afun,格式符合 CallBackFun 的格式,因此可以看作是一个 CallBackFun
printf("Afun 回调打印出字符%s!\n", p);
return 0;
}
 
int Cfun(char *p) {    // 方法 Bfun,格式符合 CallBackFun 的格式,因此可以看作是一个 CallBackFun
printf("Cfun 回调打印:%s, Nice to meet you!\n", p);
return 0;
}
 
int call(CallBackFun pCallBack, char *p) { // 执行回调函数,方式一:通过命名方式
printf("call 直接打印出字符%s!\n", p);
pCallBack(p);
return 0;
}
 
// int call2(char *p, int (*ptr)(char *p))
int call2(char *p, int (*ptr)()) { // 执行回调函数,方式二:直接通过方法指针
printf("==============\n", p);
(*ptr)(p);
}
 
int main() {
 
char *p = "hello";
 
call(Afun, p);
call(Cfun, p);
 
call2(p, Afun);
call2(p, Cfun);
 
return 0;
}

Java中回调函数的实现

在C/C++中,要用回调函数,被掉函数需要告诉调用者自己的指针地址,但在JAVA中没有指针,怎么办?我们可以通过接口(interface)来实现定义回调函数。

假设我是程序员A,以下是我的程序a:

public class Caller{
private MyCallInterface mcl;
public Caller(){}
public setCallfuc(MyCallInterface mc){
this.mc=mc;
}
public call(){
my.func();
}
}

我还需要定义一个接口,以便程序员B根据我的定义编写程序实现接口。

public interface MyCallInterface{
public void func();
}

于是,程序员B只需要实现这个接口就能达到回调的目的了,测试主函数:

public static void main(String args[]){
Caller call=new Caller();
call.setCallfuc(new  MyCallInterface(){
 
//定义func方法
 
public void func(){{
 
TestObject.testMethod();
 
}
 
});
 
call.call();
}

高级话题——Hibernate 中的回调模式应用

package hibernate.template;
 
import org.hibernate.HibernateException;
import org.hibernate.Session;
 
public interface HibernateCallBack {
// 回掉接口HibernateCallBack
// session 是用于操作数据库的!实现了此接口 对session 操作就能操作数据库!
public abstract Object execute(Session session) throws HibernateException;
}
 
//下面这个类 其实起到了 框架( 抽象类)的作用 。
 
package hibernate.template;
 
import org.hibernate.HibernateException;
import org.hibernate.Session;
import org.hibernate.Transaction;
import org.hibernate.cfg.Configuration;
 
public class HibernateTemplate {
public static Object run(HibernateCallBack callback)
throws HibernateException {
Session session = null;
Transaction tx = null;
try {
session = new Configuration().configure().buildSessionFactory()
.openSession();
tx = session.beginTransaction();
callback.execute(session)  // 用于操作数据库!
Object result = callback.execute(session);
tx.commit();
session.flush();
return result;
} catch (HibernateException e) {
tx.rollback();
return null;
} finally {
session.close();
}
}

}
先来测试一下:

package hibernate.text;
 
import hibernate.orm.Person;
import hibernate.orm.PersonDaoImpl;
 
public class Text {
 
public static void main(String[] args) {
 
HibernateTemplate.run(new HibernateCallBack() {
public Object execute(Session session) throws HibernateException {
Person p = new Person();
p.setName("aeeewaaaa");
p.setPassword("zzzzzzzzzzz");
/p.setUid("111111");
session.save(p);
return null;
}
});
}
}

Leave a Comment.