按关键词阅读:
作者 |小z同学
来源 | urlify.cn/uAZrMz
在一个应用系统中 , 不论使用何种编程语言 , 模块之间要进行调用 , 仅存在三种方式:同步调用、异步调用、回调 。 本文就其中回调方式进行详细解读 , 并通过匿名内部类的手段 , 在最后实现一个同步回调的过程 。
一、回调的意义在学习回调之前 , 我们需要知道使用回调的原因 , 和回调的应用场景 。
不如先思考两个问题:
- 栈底对栈顶通常是不可见的 , 但是栈顶有时需要直接调用栈底
- 上级派下级做事 , 在此期间 , 下级可能需要通过上级获取高权限的协助
二、如何实现同步回调本文对同步回调的业务需求如下:
- 回调方调用调用方进行数据爬取
- 调用方调用回调方进行数据存储
- 调用方调用回调方进行日志记录
文章插图
相应代码如下:
public interface Handler {void handle(String info);}public class Task {private String info;private void setInfo(String info) {this.info = info;}public void call() {Crawler.getInstance().crawl(new Handler() {@Overridepublic void handle(String info) {setInfo(info);}});}}public class Crawler {private static Crawler instance = null;public static Crawler getInstance() {if (instance == null) {instance = new Crawler();}return instance;}private String getInfo() {return "the info from crawler";}public void crawl(Handler handler) {handler.handle(getInfo());}}
三、遇到的问题如果我们使用代码来实现上述回调过程 , 不难会发现这样一个问题:Task调用Crawler , Crawler调用Handler , Hanlder调用Task 。 很明显 , 此处存在一个环 , 产生了循环依赖的问题 , 而接口可以为我们提供良好的解决方案 。文章插图
四、为什么通过匿名内部类的方式用 Java 实现同步回调有许多方式 , 为什么我们要通过匿名内部类的方式来实现回调 , 直接回调不香吗?
不妨先看看直接回调的顺序图:
文章插图
相应代码如下:
public interface Handler {void handle(String info);}public class Task implements Handler{private String info;private void setInfo(String info) {this.info = info;}public void call() {Crawler.getInstance().crawl(this);}@Overridepublic void handle(String info) {setInfo(info);}}public class Crawler {private static Crawler instance = null;public static Crawler getInstance() {if (instance == null) {instance = new Crawler();}return instance;}private String getInfo() {return "the info from crawler";}public void crawl(Handler handler) {handler.handle(getInfo());}}
直接回调带来的最大问题便是回调接口的暴露 , 也就是说回调接口不一定用于回调 , 也可以用于直接访问 。 这在业务层面的设计上是绝对不允许的 , 而匿名内部类在执行回调等特定业务的同时 , 可以很好的对外隐藏用于回调的接口 。五、总结
- 常规类不保证接口安全性:常规接口通常可以设定权限 , 但不可以指定访问类 , 也就是说要么都可以访问 , 要么都拒绝访问 。 而内部类中接口可以指定访问类 。
- 内部类保证接口安全性:内部类接口通常是对外隐藏的 , 那么如何使得内部类对指定访问类暴露呢?方法很简单 , 只需要通过外部类实例化内部类 , 并对指定类传参 , 便可以使得指定类对内部类可访问 。
- 内部类的安全性加上其对外部类的完全权限 , 这使得其成为实现回调的首选方案 。 在JAVA8中 , lambda表达式本质上就是匿名内部类的语法糖 。
参考链接
【如何用匿名内部类实现 Java 同步回调】[1] <
稿源:(未知)
【傻大方】网址:http://www.shadafang.com/c/111T320362020.html
标题:如何用匿名内部类实现 Java 同步回调