不积跬步,无以至千里;不积小流,无以成江海。
Java语言基础
Java接口回调机制
回调:模块之间一般都存在一定的调用关系,从调用方式上看,可以分为三类:同步调用、异步调用和回调。同步调用是一种阻塞式调用,即在函数A的函数体里通过书写函数B的函数名来调用之,使内存中对应函数B的代码得以执行。异步调用是一种类似消息或事件的机制解决了同步阻塞的问题,例如 A通知 B后,他们各走各的路,互不影响,不用像同步调用那样, A通知 B后,非得等到 B走完后, A才继续走 。回调是一种双向的调用模式,也就是说,被调用的接口被调用时也会调用对方的接口,例如A要调用B,B在执行完又要调用A。
先看同步调用,有类A和类B,分别有a()和b()方法,其中a()中会调用b()方法:
class A { public void a() { new B().b(); a1(); } public void a1() { System.out.println("I am a1 method!"); } } class B { public void b() { System.out.println("I am b method!"); } } public class Test { public static void main(String[] args) { // TODO Auto-generated method stub A aa = new A(); aa.a(); } }
程序输出:
I am b method! I am a1 method!
如果b()方法的执行时间较短的话,这样调用就好。但是,如果执行时间较长的话,a()方法里往下的代码无法继续执行,会一直等待b()方法执行完。这就是方法的同步调用。缺点是,一个方法执行时间长或阻塞,会造成整个a()方法的流程阻塞。
为解决这个问题,就出现了方法的异步调用,类A的a()方法可以采用另起线程的方式来调用b()方法。这种方式也会有种问题,如果b()的执行结果不影响a()方法中下面的执行,就这样调用就好,但是,如过下面的代码需要b()返回的结果,则必须通过什么途径对b()方法执行结果进行监听呢?
Java中可以通过Callable的方式可以实现这一点:在这里,我们先简单的给A类放一个callBack()函数,来当作回调函数。每次b()方法执行完就会主动调用A类的callBack()方法,这也是一种双重调用:
class AA { public void a() { System.out.println("2" + this); new BB().b(this); System.out.println("4" + this); a1(); } public void a1() { System.out.println("I am a1 method!"); } public void callBack() { System.out.println("This is callBack!"); } } class BB { public void b(AA aaa) { System.out.println("3" + aaa); System.out.println("I am b method!"); aaa.callBack(); } } public class Test { public static void main(String[] args) { // TODO Auto-generated method stub AA aa = new AA(); System.out.println("1" + aa); aa.a(); } }
程序输出:
1Rollback.AA@15db9742 2Rollback.AA@15db9742 3Rollback.AA@15db9742 I am b method! This is callBack! 4Rollback.AA@15db9742 I am a1 method!
但是以上场景适合于只有A来调用B的b()方法,而也是只通知了A。如果有跟A类一样的C、D类,都需要调用b()方法,且要实时等待b()的执行结果,怎么办?针对这种需要多态的应用场景,我们要用上接口了,我们可以把回调这一行为抽象出来,让所有要调用b()方法的类都去实现这个抽象,我们把A、D中需要b的返回结果做其他事的方法都抽象到一个接口中,就叫它callBack:
interface CallBackInterface { public void callBack(); } class A implements CallBackInterface { public void a() { System.out.println("2" + " " + this); new B().b(this); System.out.println("4" + " " + this); // a1(); } public void a1() { System.out.println("I am a1 method!"); } public void callBack() { a1(); } } class C implements CallBackInterface { public void c() { System.out.println("6" + " " + this); new B().b(this); System.out.println("8" + " " + this); // c1(); } public void c1() { System.out.println("I am c1 method!"); } public void callBack() { c1(); } } class B { public void b(CallBackInterface temp) { System.out.println("3 or 7" + " " + temp); System.out.println("I am b method!"); temp.callBack(); } } public class Test { public static void main(String[] args) { // TODO Auto-generated method stub A aa = new A(); System.out.println("1" + " " + aa); aa.a(); C cc = new C(); System.out.println("5" + " " + cc); cc.c(); System.out.println("end"); } }
程序输出:
1 Rollback_end.A@15db9742 2 Rollback_end.A@15db9742 3 or 7 Rollback_end.A@15db9742 I am b method! I am a1 method! 4 Rollback_end.A@15db9742 5 Rollback_end.C@6d06d69c 6 Rollback_end.C@6d06d69c 3 or 7 Rollback_end.C@6d06d69c I am b method! I am c1 method! 8 Rollback_end.C@6d06d69c end