Java中的回调函数

176 阅读2分钟

回调函数

今天在学习代理模式的cglib动态代理的时候看到了一个回调函数,然后发现自己不太理解这个概念,在查询资料之后总结并记个笔记。

用一个例子来表示:我给朋友打电话叫他叫他约别人出来玩,然后我去做别的事情。那么代码实现就是:

public class Me {
    callFriend(Friend friend) {
        System.out.println("我给朋友打电话");
        doSomethingElse();
    }
    doSomethingElse() {
        System.out.println("我做别的事情");
    }
}

而朋友在约完别人后需要告诉我是否成功的约到了,那么他就需要打电话告诉我,普通的按代码实现就是:

public class Friend {
    callOthers() {
        System.out.println("朋友通知其他人");
    }
    callMe() {
        System.out.println("告诉我结果");
    }
}

而可以看到如果这样写这段代码,我不能真正意义上的通知朋友,想要真正意义让我叫朋友通知别人 的时候马上做,就需要在我打电话给朋友之后,用朋友调用他的callOthers方法,即:

public class Me {
    callFriend(Friend friend) {
        System.out.println("我给朋友打电话");
        friend.callOthers();
        doSomethingElse();
    }
    doSomethingElse() {
        System.out.println("我做别的事情");
    }
}

但是我们会发现还有一个问题,那就是朋友不能打电话通知我,那我们应该给朋友一个接口让他打电话回来,改完后则为:

public class Me {
    callFriend(Friend friend) {
        System.out.println("我给朋友打电话");
        friend.callOthers();
        doSomethingElse();
    }
    doSomethingElse() {
        System.out.println("我做别的事情");
    }
    recieveMe() {
        System.out.println("朋友通知我");
    }
}

public class Friend {
    private Me me;
    callOthers() {
        System.out.println("朋友通知其他人");
    }
    //callMe() {
    //    System.out.println("告诉我结果");
    //}
    me.receiveMe();
}

但是新的问题又来了,我们不能在朋友联系他人的时候做别的事情,那么应该为朋友新建一个线程,进行等待:

public class Friend {
    private Me me;
    callOthers(Me me) throws InterruptedException {
         System.out.println("朋友接到我的电话并通知其他人");
 ​
         new Thread(new Runnable() {
             public void run() {
                 try {
                     System.out.println("朋友正在电话联系中....");
                     sleep(5000);
                     System.out.println("朋友已经约好了,准备给我回电话");
                     me.receiveMe();
                 } catch (InterruptedException e) {
                     e.printStackTrace();
                 }
             }
         }).start();
     }
    //callMe() {
    //    System.out.println("告诉我结果");
    //}
    me.receiveMe();
}

那么这就完成了一个回调函数,其中的receiveMe就是一个回调函数。

但是如果很多人都需要被通知,那么每个人都要写一个receive方法,这显然使代码极大的冗余了,为了解决这个问题,Java帮我们将它抽取了出来,在Java中这个接口叫做Callable,他定义了一个call方法,当我们需要被别人回调通知的时候,我们只需要实现callable方法既可以完成。 例如:我需要被别人通知,那么我只需要实现Callable接口并且实现call方法,而朋友只需要调用我这个call方法就可以通知我。