Java中回调函数详解

Java的中回调函数详解

0.前言

恕我直言,网上的blog大多数都是抄袭。而且参考价值不高。于是有了写本博文的想法。

1.背景

看到网上一个blog,讲得例子挺好,打电话那个也太俗套了嘛。这里我就以该blog中的例子,详细介绍一下我理解的回调函数。

2.定义

这里说出我所认为正确的定义【如果有道友不赞同,请不吝指正】:
在A类中调用B类中的方法c【实现这个很简单,比如说:直接在A类中使用类B对象的b.method()即可】,然后B类反过来调用A类的方法D,这个方法D就叫做回调方法。
实现过程如下:

  • 定义一个接口CallBack【定义这个接口的目的在于抽象】
  • Class A实现接口CallBack
  • Class A中包涵一个类B的引用b
  • Class B中有一个方法f,它的入参有CallBack类对象callback;如f(CallBack callBack,String …)
    所以整个过程的调用关系就是:b.f => ··· => callBack.method => a.method【由b.f调用 callBack的method方法之前,我使用的符号是 => ··· =>,这就代表,调用回调函数可能不是一步完成的,中间可能有许多间接的其它函数调用】

3.需求

微信充值话费相信大多数同志都有经历,通常需要如下几个步骤:

  • 01.首先微信客户端调用服务器的接口进行充值操作,
  • 02.但是服务器端需要完成的内容就比较多了,比如:银行完成转账,运营商进行充值等;如果需要一直等待【同步】服务器端完成这个操作,就需要花费很长的时间;但是如果采取异步就不会有这个问题。于是这个过程就采用异步手法。
  • 03.在手机上完成微信充值之后会收到充值成功的界面,但是实际上充值并未成功【只是显示微信缴费成功而已】。
  • 04.实际的成功【比如说10001给你发短信才表示实际充值成功】,那么这个发短信提示的功能就可以使用回调实现。
    上述这个过程,如果需要使用Java该怎么实现呢?

4.代码

  • CallBack接口
/**
 * 1.CallBack is only an interface. And have a simple method.
 */
public interface CallBack {
    public void notifyToUser();
}
  • WeChat类
package wechat;

/**
 *
 */
public class WeChat implements CallBack{
    public String weChatId;//wechat id
    public String name;//实际用户名
    public double money;//充值金额
    public Server server = new Server();//维持一个Server的引用

    public WeChat(String name,double money)
    {
        this.name = name;
        this.money = money;
    }

    public void pay(){//充值
        System.out.println("01. 微信客户端接到用户"+this.name+"充值的请求,准备调用方法payToTelecom,进行充值:");
        server.payToTelecom(WeChat.this);//将自己【WeChat这个对象传入参数中】
        System.out.println("05. 充值成功消息已通知用户,payToTelecom()调用完毕");
    }

    //实现Callback中通知用户的方法
    @Override
    public void notifyToUser() {
        System.out.println("04. 尊敬的客户,您已成功充值100元。" +
                "查询余额请直接回复102、登录欢go网站(www.189.cn)、欢go客户端。[中国电信上海公司]");
    }
}
  • Server类
package wechat;

public class Server {
    public void payToTelecom(WeChat weChatUser){//给中国移动支付
        System.out.println("02. 向中国电信为用户:"+weChatUser.name+"支付"+weChatUser.money+"元");
        System.out.println("03. 收取客户:"+weChatUser.name+" 0.1%的手续费");
        this.notifyToWeChat(weChatUser);
    }

    public void notifyToWeChat(WeChat weChatUser){
        weChatUser.notifyToUser();
    }
}
  • TestMain类
package wechat;

public class TestMain {
    public static void main(String[] args) {
        WeChat weChat = new WeChat("LittleLawson", 100);
        weChat.pay();
    }
}

上述代码可在如下链接https://github.com/LittleLawson/TestCallBack中获取,在代码中,我添加了一个AliPay类,用于体现接口CallBack并非多余。

4.分析

上述代码的调用过程如下:
weChatUser.pay() => server.payToTelecomByWeChat() => server.notifyToWeChat() => weChatUser.notifyToUser()
可以看到最开始由WeChat.pay()出发,最后回到weChatUser.notifyToUser()方法【注意他们都是WeChat这个类中的方法】,故称回调。

5.总结

想必还在思考回调函数的实现过程的各位同学和我一样——还是Java入门者。这里我抛出几个问题,大家可以思考一下:

  • 01.为什么需要回调函数?
    我认为,回调函数的存在就是为了告诉调用者“我调用成功/失败了”。比如说上述的微信充值例子,如果不知道自己是否充值成功/失败,那要微信有个鸟用?【充值成功/失败的标准是:运营商收到这笔钱,而不是微信收到,所以需要Server这个类触发回调,而不是WeChat这个类触发回调。】

  • 02.经典的回调函数调用的使用案例有哪些?
    这个我正在收集,后期会更新出来。

6.参考资料

  • https://blog.csdn.net/xiaanming/article/details/8703708/【好文章】

  • https://www.cnblogs.com/liboBlog/p/7107440.html【本文素材源自于此】

  • https://blog.csdn.net/jiayi_yao/article/details/51046526【对回调函数的理解正确,而且讲解了为什么需要将notifyToUser()这个方法抽象成单独的CallBack接口中。】

  • https://blog.csdn.net/allen_zhao_2012/article/details/8056665#commentsedit【不过我认为在这篇文章中,该作者对回调的理解是错误的】

你可能感兴趣的:(#,Java)