模块间调用分为三种
2.1 其实回调也是一种普通的调用。我们在一个类中定义好行为,而具体什么时候调用,交给另一个类的方法,其实就是传递引用。我们先来看下下面的调用
public class CallbackTest {
    public static void main(String[] args) {
        CallbackTest callbackTest = new CallbackTest();
        callbackTest.test();
    }
    public void test() {
        Callback callback = new Callback();
        Foo foo = new Foo();
        foo.test(callback); // 将callback引用传入
    }
}
class Callback { // 普通的类
    public void call(String name) { // 参数具体是什么是调用的时候指定的
        System.out.println("call: " + name); // 声明行为
    }
}
class Foo { // 普通的类
    public void test(Callback callback) {
        try {
            Thread.sleep(2000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        callback.call("hello"); // 具体什么时候执行
    }
}在上面的代码中,我们分别有两个普通的类Callback和Foo,Foo的test方法接受一个Callback对象,并调用Callback对象的call方法。这很好理解。
2.2 我们同样可以写一个Callback的子类,来实现自己的方法。
public class CallbackTest {
    public static void main(String[] args) {
        CallbackTest callbackTest = new CallbackTest();
        callbackTest.test();
    }
    public void test() {
        Callback callback = new MyCallback(); // 使用子类覆盖
        Foo foo = new Foo();
        foo.test(callback); // 将callback引用传入
    }
}
class Callback { // 普通的类
    public void call(String name) {
        System.out.println("call: " + name);
    }
}
class MyCallback extends Callback {
    public void call(String name) {
        System.out.println("my call: " + name); // 声明自己的行为
    }
}
class Foo { // 普通的类
    public void test(Callback callback) {
        try {
            Thread.sleep(2000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        callback.call("hello");
    }
}上述代码中Callback更通常的写法应该是写成接口或者抽象类。上述代码还可以有一个变形,就是让public类继承或实现Callback,如
public class CallbackTest extends Callback{
    public static void main(String[] args) {
        CallbackTest callbackTest = new CallbackTest();
        callbackTest.test();
    }
    public void test() {
//        Callback callback = new MyCallback(); 
        Foo foo = new Foo();
        foo.test(this); // 将自己传进去
    }
    public void call(String name) {
        System.out.println("my call: " + name); // 定义行为
    }
}
class Callback { // 普通的类
    public void call(String name) {
        System.out.println("call: " + name);
    }
}
class Foo { // 普通的类
    public void test(Callback callback) {
        try {
            Thread.sleep(2000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        callback.call("hello");
    }
}2.3 使用匿名类。上述代码可以简化成使用匿名内部类
public class CallbackTest {
    public static void main(String[] args) {
        CallbackTest callbackTest = new CallbackTest();
        callbackTest.test();
    }
    public void test() {
//        Callback callback = new MyCallback(); 
        Foo foo = new Foo();
        foo.test(new Callback() { // 匿名内部类,通常写法Callback是一个接口,不过普通类也可以
            public void call(String name) {
                System.out.println("my call: " + name);
            }
        }); // 将callback引用传入
    }
}
class Callback { // 普通的类
    public void call(String name) {
        System.out.println("call: " + name);
    }
}
class Foo { // 普通的类
    public void test(Callback callback) {
        try {
            Thread.sleep(2000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        callback.call("hello");
    }
}2.4 匿名内部类可以访问外部类的方法,因此我们可以将具体的实现放到外部类中。
public class CallbackTest {
    public static void main(String[] args) {
        CallbackTest callbackTest = new CallbackTest();
        callbackTest.test();
    }
    public void test() {
//        Callback callback = new MyCallback();
        Foo foo = new Foo();
        foo.test(new Callback() {
            public void call(String name) {
                myCall(name); // 调用外部类的方法
            }
        }); // 将callback引用传入
    }
    
    // 具体要进行的行为
    public void myCall(String name) {
        System.out.println("my call: " + name);
    }
}
class Callback { // 普通的类
    public void call(String name) {
        System.out.println("call: " + name);
    }
}
class Foo { // 普通的类
    public void test(Callback callback) {
        try {
            Thread.sleep(2000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        callback.call("hello");
    }
}2.5 回调函数可以加上状态。上面的Callback都是无状态的,我们可以给Callbakc加上状态,然后再调用的时候设置Callback状态,这样通过Callback的引用就可以执行任务执行的状态,类似java中的Future。
public class CallbackTest {
    public static void main(String[] args) {
        CallbackTest callbackTest = new CallbackTest();
        callbackTest.test();
    }
    public void test() {
        Callback callback = new MyCallback(); // 使用子类覆盖
        Foo foo = new Foo();
        foo.test(callback); // 将callback引用传入
        while (!callback.complete) { // 通过callback的引用可以知道调用的状态,是不是项java中的Future?
            try {
                Thread.sleep(500);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            System.out.println("not complete");
        }
        System.out.println("complete");
    }
}
class Callback { // 普通的类
    public boolean complete = false; // 包含状态
    public void call(String name) {
        System.out.println("call: " + name);
    }
}
class MyCallback extends Callback {
    public void call(String name) {
        System.out.println("my call: " + name); // 声明自己的行为
    }
}
class Foo { // 普通的类
    public void test(Callback callback) {
        try {
            Thread.sleep(2000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        callback.call("hello");
        callback.complete = true;
    }
}其实回调也是普通的调用,本质同一个引用,被不同的类调用。回调通常和匿名内部类一起来用使得看起来有些复杂,如果能拆开来看的话就会好理解。回调的作用可以理解为将动作和动作开始的时间分离:在自己的类中只定义应该怎么做,然后把这个类的引用给另一个类的方法去调用。
原文:https://www.cnblogs.com/set-cookie/p/8996951.html