Java中的回调函数
Java中回调是什么
调用
1️⃣基本回调
A <--> B
A对象 ----B.fb(A) -----> B对象 // 调用B的fb()时传入A本身(this)
B对象(fb 方法)----->A.fa()------>A对象 // B就可以直接调用A,fa()就是回调方法
2️⃣接口回调
A <--> B
3️⃣异步回调
AImpl ----B.fb(IA) -----> B对象 // B.fb(IA)单独起一个线程执行
代码
概念说完了,下面就上代码...
同步调用
码农(Programmer)现在需要做几件事情:
- 敲代码一整天(敲代码)
- 将今天工作代码上传到Github上(上传代码)
- 备注一下完成日期(记录下完成的日期)
下面我们用程序去实现:程序一共就三个类:
- Programmer(码农类)
- Github(Github类 用于保存码农提交的代码)
- TestDemo(用于测试并显示结果)
如下所示:
java
public class Programmer {
public void code(){
System.out.println("coding"); //step1.写代码
new Github().push(); //step2.提交代码
recordToday(); //step3. 记录的日期
}
public void recordToday(){
System.out.println("i'm done " + new Date());
}
}java
// 只负责上传代码
public class Github {
public void push(){
System.out.println("git push");
}
}java
// 让Programmer工作
public class TestDemo {
public static void main(String args[]){
Programmer p = new Programmer();
p.code();
}
}执行结果如下:
基本回调
可否给苦逼程序员一条生路,让他提交代码之后就下班,像记录日期:recodeToday()这种事让Github类去负责。
换句话说,Github类的push()函数执行完后,Github类去调用Programmer类的recodeToday()方法,而不是Programmer自己去调用,略微改动后
java
// A
public class Programmer {
public void code(){
System.out.println("coding");
new Github().push(this); // B.fb(this)
// 这里没有 step3,码农没有自己调用 recordToday()方法.
}
// A.fa(),回调方法
public void recordToday(){
System.out.println("i'm done " + new Date());
}
}java
// B
public class Github {
public void push(Programmer p ){ // push的参数多了Programmer类
System.out.println("git push");
p.recordToday(); // 执行回调
}
}最后执行结果不变
接口回调(可以结合 lambda)
如果现在不只有Programmer了还有Teacher和Student,那GitHub的push方法难道要再重载?最好的办法是push依赖接口
java
// IA,回调接口
public interface RecodeInterface {
public void recode();
}java
// B
public class Github {
public void push(RecodeInterface r ){ // 依赖接口
System.out.println("git push");
r.recode(); // A.fa(),执行回调
}
}java
// AImpl,实现了接口
public class Programmer implements RecodeInterface{
public void code(){
System.out.println("coding");
new Github().push(this); // B.fb(A)
}
@Override
public void recode() { // 回调函数
System.out.println("Programmer done " + new Date());
}
}java
public class Student {
public void code(){
System.out.println("coding");
new Github().push(new StudentRecodeToday());
}
// AImpl,也可以单独抽象出一个内部类
public class StudentRecodeToday implements RecodeInterface{
@Override
public void recode() {
System.out.println("Student done "+ new Date());
}
}
}✅使用 lambda 表达式
java
public class Student {
public void code() {
System.out.println("coding");
new Github().push(() -> System.out.println("Student done " + new Date()));
}
// AImpl,也可以单独抽象出一个内部类
// public class StudentRecodeToday implements RecodeInterface{
// @Override
// public void recode() {
// System.out.println("Student done "+ new Date());
// }
// }
}异步回调
java
// IA,回调接口
public interface mycallback {
void onData(Object message); // 正常处理
void onError(Exception e); // 异常处理
}java
// AImpl,实现了回到接口
public class Client implements mycallback{
int count=0;
@Override
public void onData(Object message) {
count++;
System.out.println("received message:"+message.toString());
}
@Override
public void onError(Exception e) {
System.out.println("error!");
}
public void send(String message){
// 异步回调核心!!! 为B.fb(IA)单独启动一个线程
Thread thread=new Thread(new Server(Client.this,message));
thread.start();
}
}java
// B
public class Server implements Runnable{
mycallback c;
Object message;
public Server(mycallback cl,Object o){
c=cl;
message=o;
}
@Override
public void run() {
try {
c.onData(message+" after server"); // 执行回调
}catch (Exception e){
c.onError(e);
}
}
}启动类
java
public class Work{
public static void main(String[] args){
Client c1=new Client();
c1.send(hello);
System.out.println("do others...");
}
}结果
java
do others...
received message:hello