java的回调很有意思,是通过内部类实现的。下面我们来看看Think in JAVA 上提供的有趣例子。
public class Callee1 implements Incrementable {
private int i = 0;
@Override
public void increment() {
i++;
System.out.println(i);
}
}
↓↓↓
外围类继承了MyIncrement ,MyIncrement 类中有一个increment()方法。
这里故意设置外围类有一个increment()方法,因为内部类也有一个increment()方法。
作者的意思是想说内部类的方法可以与外围类的方法重名,且互相没有影响。
甚至可以有多个内部类,每个内部类都可以有一个同名的方法。
这样就可以同名的方法,但行为不同。
↓↓↓
class MyIncrement { //MyIncrement 类中有一个increment()方法
public void increment(){System.out.println("Other operation");}
static void f(MyIncrement mi) {mi.increment();}
}
class Callee2 extends MyIncrement {//外围类继承了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();
}
}
↓↓↓
内部类提供一个方法getCallbackReference ()将自己的引用返回,Caller类获得内部类Closure的引用。
Caller类在自己的方法go()中使用内部类的引用,并通过引用调用内部类的方法。
此过程就形成了回调。
这样就可以在运行时通过持有的内部类Caller的引用,进行运行时调用。
↓↓↓
class Caller {
private Incrementable callbackReference;
Caller(Incrementable cbh) {callbackReference = cbh;}
void go() {callbackReference.increment();}
}
public class Callbacks {
public static void main(String[] args) {
Callee1 c1 = new Callee1();
Callee2 c2 = new Callee2();
MyIncrement.f(c2);
// Caller caller1 = new Caller(c1);
Caller caller2 = new Caller(c2.getCallbackReference());
//
// caller1.go();
// caller1.go();
caller2.go();
// caller2.go();
}
}
↓↓↓
书上还有一句话说的很有意思:无论谁获得内部类Closure 的引用作为参数,都只能调用increment()方法,除此之外没有其他功能。
因为内部类Closure 实现了接口Incrementable ,并且getCallbackReference()方法返回的也是Incrementable 类型。
↓↓↓
public interface Incrementable {
void increment();
}