There is always a certain interface between modules. From the perspective of calling methods, they can be divided into three categories: synchronous calls, callbacks and asynchronous calls. The following focuses on the callback mechanism in detail.
1. Overview
The callback mechanism in Java is a relatively common mechanism, but it may be used less in your program. In some large programs Callback mechanisms can be found everywhere in the framework. This article will slowly approach Java's callback mechanism through some specific examples.
2. Callback
The so-called callback: Class A calls a method C in class B, and then class B in turn calls a method in class A. D, this method D is called the callback method. In actual use, there will be different callback forms, such as the following.
2.1 Synchronous callback
Here I assume such a situation.
Director B of company A told his subordinate (project manager C) that he wanted to do a survey, but he didn’t need C to do it himself. You can ask manager C to arrange for programmer D below him to complete it. Manager C found programmer D and told him that he now had to complete a research task. And tell manager C the results of the survey. If there are any problems, you still have to continue. Because here C asks D to do something, and then D still has to communicate the result with C. This is the callback model. The following is a class diagram of a general callback:
##First we need to have a callback interface CallbackInterfacepublic interface CallbackInterface { public boolean check(int result); }
public class Manager implements CallbackInterface { private Programmer programmer = null; public Manager(Programmer _programmer) { this.programmer = _programmer; } /** * 用于 Boss 下达的委托 */ public void entrust() { arrange(); } // 进行安排下属进行 study 工作 private void arrange() { System.out.println("Manager 正在为 Programmer 安排工作"); programmer.study(Manager.this); System.out.println("为 Programmer 安排工作已经完成,Manager 做其他的事情去了。"); } @Override public boolean check(int result) { if (result == 5) { return true; } return false; } }
public class Programmer { public void study(CallbackInterface callback) { int result = 0; do { result++; System.out.println("第 " + result + " 次研究的结果"); } while (!callback.check(result)); System.out.println("调研任务结束"); } }
public class Boss { public static void main(String[] args) { Manager manager = new Manager(new Programmer()); manager.entrust(); } }
Results of the 1st study
Results of the 2nd study
Results of the 3rd study
Results of the 4th study
Results of the 5th study
End of research task
Arrangement work for Programmer has been completed, Manager Went to do other things.
So, here we need to modify the code of the Programmer class as follows:
public class Programmer { public Programmer() { } public void study(CallbackInterface callback) { new StudyThread(callback).start(); } // --------------------------- Programmer 正在做的工作 --------------------------- class StudyThread extends Thread { CallbackInterface callback = null; public StudyThread(CallbackInterface _callback) { callback = _callback; } @Override public void run() { int result = 0; do { result++; System.out.println("第 " + result + " 次研究的结果"); } while (!callback.check(result)); System.out.println("调研任务结束"); } } }
Arranging work for Programmer has been completed, and Manager has gone to do other things.
Results of the 1st study
Results of the 2nd study
Results of the 3rd study
Results of the 4th study
Results of the 5th study
Research tasks End
Incrementable.java
interface Incrementable { void increment(); }
class Callee1 implements Incrementable { private int i = 0; @Override public void increment() { i++; System.out.println(i); } }
public class Callbacks { public static void main(String[] args) { Callee1 callee1 = new Callee1(); callee1.increment(); } }
class Caller { private Incrementable callbackReference; public Caller(Incrementable _callbackReference) { callbackReference = _callbackReference; } void go() { callbackReference.increment(); } }
public class Callbacks { public static void main(String[] args) { Callee1 callee1 = new Callee1(); Caller caller1 = new Caller(callee1); caller1.go(); } }
对于到目前为止的程序代码,完全可以对比上面项目经理安排程序员调研技术难题的代码。有异曲同工之妙。
2.3.3 闭包回调
相比于正常的回调,闭包回调的核心自然是在于闭包,也就是对作用域的控制。
现在假设有一个用户(其他程序员)自定义了一个 MyInCrement 类,同时包含了一个 increment 的方法。如下:
class MyInCrement { public void increment() { System.out.println("MyCrement.increment"); } static void f(MyInCrement increment) { increment.increment(); } }
另外有一个类 Callee2 继承自上面这个类:
class Callee2 extends MyInCrement { private int i = 0; public void increment() { super.increment(); i++; System.out.println(i); } }
显而易见这里如果要调用 increment() 方法,就变成了一般的函数调用了。所以这里我们需要修改上面的 Callee2 类,修改的目标就是让 Callee2 类可以兼容 MyInCrement 类的 increment() 方法和 Incrementable 的 increment() 方法。修改后:
class Callee2 extends MyInCrement { private int i = 0; public void increment() { super.increment(); i++; System.out.println(i); } private class Closure implements Incrementable { @Override public void increment() { Callee2.this.increment(); } } Incrementable getCallbackReference() { return new Closure(); } }
注意,这里的 Closure 类是一个私有的类,这是一个闭包的要素。因为 Closure 类是私有的,那么就要有一个对外开放的接口,用来对 Closure 对象的操作,这里就是上面的 getCallbackReference() 方法。 Caller 类则没有改变。
对于测试客户端就直接看代码吧:
public class Callbacks { public static void main(String[] args) { Callee2 callee2 = new Callee2(); Caller caller2 = new Caller(callee2.getCallbackReference()); caller2.go(); } }
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持PHP中文网。
更多Detailed explanation of Javas callback mechanism相关文章请关注PHP中文网!