精华内容
下载资源
问答
  • 原标题:Java回调机制是什么意思?一、Java回调机制是什么意思Java中的回调机制是什么意思呢?所谓回调:就是A类中调用B类中的某个方法C,然后B类中反过来调用A类中的方法D,D这个方法就叫回调方法。百度百科中对Java...

    原标题:Java回调机制是什么意思?

    一、Java回调机制是什么意思

    Java中的回调机制是什么意思呢?所谓回调:就是A类中调用B类中的某个方法C,然后B类中反过来调用A类中的方法D,D这个方法就叫回调方法。百度百科中对Java回调机制是这样解释的:

    cb0eb36b8d6e188eb7dfe9b32f3933e6.gif

    软件模块之间总是存在着一定的接口,从调用方式上,可以把他们分为三类:同步调用、回调和异步调用。

    回调是一种特殊的调用,至于三种方式也有点不同。

    1、同步回调,即阻塞,单向。

    2、回调,即双向(类似自行车的两个齿轮)。

    3、异步调用,即通过异步消息进行通知。

    二、Java回调机制案例分析

    以上的概念可能理解起来有些困难,我们以CS中的异步回调为例,分享一个Java回调机制案例。

    比如这里模拟个场景:客户端发送msg给服务端,服务端处理后(5秒),回调给客户端,告知处理成功。代码如下:

    ①Java回调机制-回调接口类

    public interface CSCallBack {

    public void process(String status);

    }

    ②Java回调机制-模拟客户端类

    public class Client implements CSCallBack {

    private Server server;

    public Client(Server server) {

    this.server = server;

    }

    public void sendMsg(final String msg){

    System.out.println("客户端:发送的消息为:" + msg);

    new Thread(new Runnable() {

    @Override

    public void run() {

    server.getClientMsg(Client.this,msg);

    }

    }).start();

    System.out.println("客户端:异步发送成功");

    }

    @Override

    public void process(String status) {

    System.out.println("客户端:服务端回调状态为:" + status);

    }}

    ③Java回调机制-模拟服务端类

    public class Server {

    public void getClientMsg(CSCallBack csCallBack , String msg) {

    System.out.println("服务端:服务端接收到客户端发送的消息为:" + msg);

    // 模拟服务端需要对数据处理

    try {

    Thread.sleep(5 * 1000);

    } catch (InterruptedException e) {

    e.printStackTrace();

    }

    System.out.println("服务端:数据处理成功,返回成功状态 200");

    String status = "200";

    csCallBack.process(status);

    }}

    ④Java回调机制-测试类

    public class CallBackTest {

    public static void main(String[] args) {

    Server server = new Server();

    Client client = new Client(server);

    client.sendMsg("Server,Hello~");

    }}

    运行下测试类 — 打印结果如下:

    客户端:发送的消息为:Server,Hello~

    客户端:异步发送成功

    服务端:服务端接收到客户端发送的消息为:Server,Hello~

    (这里模拟服务端对数据处理时间,等待5秒)

    服务端:数据处理成功,返回成功状态 200

    客户端:服务端回调状态为:200

    一步一步分析下代码,核心总结如下

    1、接口作为方法参数,其实际传入引用指向的是实现类

    2、Client的sendMsg方法中,参数为final,因为要被内部类一个新的线程可以使用。这里就体现了异步。

    3、调用server的getClientMsg(),参数传入了Client本身(对应第一点)。

    三、Java回调机制的应用场景

    Java回调机制目前运用在什么场景比较多呢?从操作系统到开发者调用:

    1、Windows平台的消息机制

    2、异步调用微信接口,根据微信返回状态对出业务逻辑响应。

    3、Servlet中的Filter(过滤器)是基于回调函数,需容器支持。

    补充:其中 Filter(过滤器)和Interceptor(拦截器)的区别,拦截器基于是Java的反射机制,和容器无关。但与回调机制有异曲同工之妙。

    总之,这设计让底层代码调用高层定义(实现层)的子程序,增强了程序的灵活性。返回搜狐,查看更多

    责任编辑:

    展开全文
  • java回调函数在网上了看了些例子,比较绕,不够清晰,自己写的一个例子比较通俗,java回调其实很简单。举个例子我是类B,我有个方法叫b(),现在我要调用类A中的方法a(),写个代码就是:public class ClassB{ //我是...

    java回调函数在网上了看了些例子,比较绕,不够清晰,自己写的一个例子比较通俗,java回调其实很简单。

    举个例子我是类B,我有个方法叫b(),现在我要调用类A中的方法a(),写个代码就是:

    public class ClassB{ //我是类 B

    public void b(){ //我是类B中的方法b()

    ClassA a = new ClassA();//我现在实例化A类,为的是调用A类中的方法a()

    a.a(); //快看我现在开始调用A类中的a()方法了,代码执行到这大家都懂,就是一个普通的调用其他类的方法,

    //那么回调怎么回事,回调就是我执行a()方法结束后,需要再执行我自己(类B)的方法back()

    //回调就是这个意思,我调用你的方法,调用完你的方法后,再回过头来调用自己的方法

    //注意,有人就要说了 我在a.a()方法后面直接加上一个 back()不就行了,可以,但那不是回调函数

    //回调更像是一个约定,就是如果我调用了a()方法,那么就必须要回调,而不需要显示调用

    }

    public void backs (){

    System.out.println("我就是回调函数");//暂时不要管我,其实我就是回调函数

    }

    }

    再举个例子就是:我是老板(Boss),我有一部电话叫back,现在我安排了一个任务给员工(Emp),让他给我打印一份报表(doPrint),打印好报表后再通过我的

    电话back告诉我。那么流程就很清晰了

    public class Boss{ //我是老板

    Emp emp = new Emp();//现在我new一个员工出来

    emp.doPrint(); //我现在让这个员工去给我打印一份报表,报表打印好后直接通过back电话通知我。

    public void back(){

    System.out.println("老板报表打印好了,请你放心!");//这个是我的电话

    }

    }

    上面说了

    emp.doPrint();//报表打印好后

    back(); //直接通过back电话告诉老板,这种写法不是回调

    那么我怎么让员工emp.doPring();打印好报表后打电话给我呢。可以想象一下就是在emp.doPrint();打印报表这个方法中再次调用Boss的电话

    public class Emp(){ //员工

    public void doPrint(){ //员工开始打印报表了

    System.out.println("老板我报表打印好了");//这个时候员工把报表打印好了,再通过老板的电话通知老板,怎么做呢?

    Boss boss = new Boss();

    boss.back(); //这就是通过老板的电话在我打印好了以后,告知老板

    }

    }

    这样就实现了我doPrint();//报表打印好后,回调Boss的电话通知Boss,这就是回调

    以上都是伪代码,只是为了说明什么是回调,但是在实际应用中,都是利用接口设置回调函数的

    接口回调函数参照:http://www.ej38.com/showinfo/java-197426.html

    展开全文
  • Java回调机制解读

    2021-02-12 23:38:22
    模块间调用在一个应用系统中,无论使用何种语言开发,必然存在模块之间的调用,调用的方式分为几种:(1)同步调用同步调用是最基本并且最简单的一种调用方式,类A的方法a()调用类B的方法b(),一直等待b()方法执行完毕...

    模块间调用

    在一个应用系统中,无论使用何种语言开发,必然存在模块之间的调用,调用的方式分为几种:

    (1)同步调用

    5c40fb6a6b9a0d3da2db1e3511d25dca.png

    同步调用是最基本并且最简单的一种调用方式,类A的方法a()调用类B的方法b(),一直等待b()方法执行完毕,a()方法继续往下走。这种调用方式适用于方法b()执行时间不长的情况,因为b()方法执行时间一长或者直接阻塞的话,a()方法的余下代码是无法执行下去的,这样会造成整个流程的阻塞。

    (2)异步调用

    308110628e462dd17155984a8e63e8c5.png

    异步调用是为了解决同步调用可能出现阻塞,导致整个流程卡住而产生的一种调用方式。类A的方法方法a()通过新起线程的方式调用类B的方法b(),代码接着直接往下执行,这样无论方法b()执行时间多久,都不会阻塞住方法a()的执行。但是这种方式,由于方法a()不等待方法b()的执行完成,在方法a()需要方法b()执行结果的情况下(视具体业务而定,有些业务比如启异步线程发个微信通知、刷新一个缓存这种就没必要),必须通过一定的方式对方法b()的执行结果进行监听。在Java中,可以使用Future+Callable的方式做到这一点,具体做法可以参见我的这篇文章Java多线程21:多线程下其他组件之CyclicBarrier、Callable、Future和FutureTask。

    (3)回调

    bebb51bb41f6480b90e05f56b9cbe7ad.png

    最后是回调,回调的思想是:

    类A的a()方法调用类B的b()方法

    类B的b()方法执行完毕主动调用类A的callback()方法

    这样一种调用方式组成了上图,也就是一种双向的调用方式。

    代码示例

    接下来看一下回调的代码示例,代码模拟的是这样一种场景:老师问学生问题,学生思考完毕回答老师。

    首先定义一个回调接口,只有一个方法tellAnswer(int answer),即学生思考完毕告诉老师答案:

    48304ba5e6f9fe08f3fa1abda7d326ab.png

    1 /**

    2 * 回调接口,原文出处http://www.cnblogs.com/xrq730/p/6424471.html

    3 */

    4 public interfaceCallback {

    5

    6 public void tellAnswer(intanswer);

    7

    8 }

    48304ba5e6f9fe08f3fa1abda7d326ab.png

    定义一个老师对象,实现Callback接口:

    48304ba5e6f9fe08f3fa1abda7d326ab.png

    1 /**

    2 * 老师对象,原文出处http://www.cnblogs.com/xrq730/p/6424471.html

    3 */

    4 public class Teacher implementsCallback {

    5

    6 privateStudent student;

    7

    8 publicTeacher(Student student) {

    9 this.student =student;

    10 }

    11

    12 public voidaskQuestion() {

    13 student.resolveQuestion(this);

    14 }

    15

    16 @Override

    17 public void tellAnswer(intanswer) {

    18 System.out.println("知道了,你的答案是" +answer);

    19 }

    20

    21 }

    48304ba5e6f9fe08f3fa1abda7d326ab.png

    老师对象有两个public方法:

    (1)回调接口tellAnswer(int answer),即学生回答完毕问题之后,老师要做的事情

    (2)问问题方法askQuestion(),即向学生问问题

    接着定义一个学生接口,学生当然是解决问题,但是接收一个Callback参数,这样学生就知道解决完毕问题向谁报告:

    48304ba5e6f9fe08f3fa1abda7d326ab.png

    1 /**

    2 * 学生接口,原文出处http://www.cnblogs.com/xrq730/p/6424471.html

    3 */

    4 public interfaceStudent {

    5

    6 public voidresolveQuestion(Callback callback);

    7

    8 }

    48304ba5e6f9fe08f3fa1abda7d326ab.png

    最后定义一个具体的学生叫Ricky:

    48304ba5e6f9fe08f3fa1abda7d326ab.png

    1 /**

    2 * 一个名叫Ricky的同学解决老师提出的问题,原文出处http://www.cnblogs.com/xrq730/p/6424471.html

    3 */

    4 public class Ricky implementsStudent {

    5

    6 @Override

    7 public voidresolveQuestion(Callback callback) {

    8 //模拟解决问题

    9 try{

    10 Thread.sleep(3000);

    11 } catch(InterruptedException e) {

    12

    13 }

    14

    15 //回调,告诉老师作业写了多久

    16 callback.tellAnswer(3);

    17 }

    18

    19 }

    48304ba5e6f9fe08f3fa1abda7d326ab.png

    在解决完毕问题之后,第16行向老师报告答案。

    写一个测试类,比较简单:

    48304ba5e6f9fe08f3fa1abda7d326ab.png

    1 /**

    2 * 回调测试,原文出处http://www.cnblogs.com/xrq730/p/6424471.html

    3 */

    4 public classCallbackTest {

    5

    6 @Test

    7 public voidtestCallback() {

    8 Student student = newRicky();

    9 Teacher teacher = newTeacher(student);

    10

    11 teacher.askQuestion();

    12

    13 }

    14

    15 }

    48304ba5e6f9fe08f3fa1abda7d326ab.png

    代码运行结果就一行:

    知道了,你的答案是3

    简单总结、分析一下这个例子就是:

    (1)老师调用学生接口的方法resolveQuestion,向学生提问

    (2)学生解决完毕问题之后调用老师的回调方法tellAnswer

    这样一套流程,构成了一种双向调用的关系。

    代码分析

    分析一下上面的代码,上面的代码我这里做了两层的抽象:

    (1)将老师进行抽象

    将老师进行抽象之后,对于学生来说,就不需要关心到底是哪位老师询问我问题,只要我根据询问的问题,得出答案,然后告诉提问的老师就可以了,即使老师换了一茬又一茬,对我学生而言都是没有任何影响的

    (2)将学生进行抽象

    将学生进行抽象之后,对于老师这边来说就非常灵活,因为老师未必对一个学生进行提问,可能同时对Ricky、Jack、Lucy三个学生进行提问,这样就可以将成员变量Student改为List,这样在提问的时候遍历Student列表进行提问,然后得到每个学生的回答即可

    这个例子是一个典型的体现接口作用的例子,之所以这么说是因为我想到有些朋友可能不太明白接口的好处,不太明白接口好处的朋友可以重点看一下这个例子,多多理解。

    总结起来,回调的核心就是回调方将本身即this传递给调用方,这样调用方就可以在调用完毕之后告诉回调方它想要知道的信息。回调是一种思想、是一种机制,至于具体如何实现,如何通过代码将回调实现得优雅、实现得可扩展性比较高,一看开发者的个人水平,二看开发者对业务的理解程度。

    同步回调与异步回调

    上面的例子,可能有人会提出这样的疑问:

    这个例子需要用什么回调啊,使用同步调用的方式,学生对象回答完毕问题之后直接把回答的答案返回给老师对象不就好了?

    这个问题的提出没有任何问题,可以从两个角度去理解这个问题。

    首先,老师不仅仅想要得到学生的答案怎么办?可能这个老师是个更喜欢听学生解题思路的老师,在得到学生的答案之前,老师更想先知道学生姓名和学生的解题思路,当然有些人可以说,那我可以定义一个对象,里面加上学生的姓名和解题思路不就好了。这个说法在我看来有两个问题:

    (1)如果老师想要的数据越来越多,那么返回的对象得越来越大,而使用回调则可以进行数据分离,将一批数据放在回调方法中进行处理,至于哪些数据依具体业务而定,如果需要增加返回参数,直接在回调方法中增加即可

    (2)无法解决老师希望得到学生姓名、学生解题思路先于学生回答的答案的问题

    因此我认为简单的返回某个结果确实没有必要使用回调而可以直接使用同步调用,但是如果有多种数据需要处理且数据有主次之分,使用回调会是一种更加合适的选择,优先处理的数据放在回调方法中先处理掉。

    另外一个理解的角度则更加重要,就是标题说的同步回调和异步回调了。例子是一个同步回调的例子,意思是老师向Ricky问问题,Ricky给出答案,老师问下一个同学,得到答案之后继续问下一个同学,这是一种正常的场景,但是如果我把场景改一下:

    老师并不想One-By-One这样提问,而是同时向Ricky、Mike、Lucy、Bruce、Kate五位同学提问,让同学们自己思考,哪位同学思考好了就直接告诉老师答案即可。

    这种场景相当于是说,同学思考完毕完毕问题要有一个办法告诉老师,有两个解决方案:

    (1)使用Future+Callable的方式,等待异步线程执行结果,这相当于就是同步调用的一种变种,因为其本质还是方法返回一个结果,即学生的回答

    (2)使用异步回调,同学回答完毕问题,调用回调接口方法告诉老师答案即可。由于老师对象被抽象成了Callback接口,因此这种做法的扩展性非常好,就像之前说的,即使老师换了换了一茬又一茬,对于同学来说,只关心的是调用Callback接口回传必要的信息即可

    展开全文
  • Java回调方法详解

    2021-02-28 19:16:48
    回调在维基百科中定义为:在计算机程序设计中,回调函数,是指通过函数参数传递到其他代码的,某一块可执行代码的引用。其目的是允许底层代码调用在高层定义的子程序。举个例子可能更明白一些:以Android中用...

    回调在维基百科中定义为:

    在计算机程序设计中,回调函数,是指通过函数参数传递到其他代码的,某一块可执行代码的引用。

    其目的是允许底层代码调用在高层定义的子程序。

    举个例子可能更明白一些:以Android中用retrofit进行网络请求为例,这个是异步回调的一个例子。

    在发起网络请求之后,app可以继续其他事情,网络请求的结果一般是通过onResponse与onFailure这两个方法返回得到。看一下相关部分的代码:

    call.enqueue(new Callback() {

    @Override

    public void onResponse(Call call, Response response) {

    HistoryBean hb = response.body();

    if(hb == null) return;

    showText.append(hb.isError() + "");

    for(HistoryBean.ResultsBean rb : hb.getResults()){

    showText.append(rb.getTitle() + "/n");

    }

    }

    @Override

    public void onFailure(Call call, Throwable t) {

    }

    });

    忽略上面CallBack中的泛型,按照维基百科中的定义,匿名内部类里面的全部代码可以看成函数参数传递到其他代码的,某一块可执行代码的引用。 onResponse与onFailure这两个方法就是回调方法。底层的代码就是已经写好不变的网络请求部分,高层定义的子程序就是回调,因为具体的实现交给了使用者,所以具备了很高的灵活性。上面就是通过enqueue(Callback callback)这个方法来关联起来的。

    回调方法的步骤

    上面说的回调是很通用的概念,放到程序书写上面,就可以说:

    A类中调用B类中的某个方法C,然后B类中在反过来调用A类中的方法D,在这里面D就是回调方法。B类就是底层的代码,A类是高层的代码。

    所以通过上面的解释,我们可以推断出一些东西,为了表示D方法的通用性,我们采用接口的形式让D方法称为一个接口方法,那么如果B类要调用A类中的方法D,那势必A类要实现这个接口,这样,根据实现的不同,就会有多态性,使方法具备灵活性。

    A类要调用B类中的某个方法C,那势必A类中必须包含B的引用,要不然是无法调用的,这一步称之为注册回调接口。那么如何实现B类中反过来调用A类中的方法D呢,直接通过上面的方法C,B类中的方法C是接受一个接口类型的参数,那么只需要在C方法中,用这个接口类型的参数去调用D方法,就实现了在B类中反过来调用A类中的方法D,这一步称之为调用回调接口。

    这也就实现了B类的C方法中,需要反过来再调用A类中的D方法,这就是回调。A调用B是直调,可以看成高层的代码用底层的API,我们经常这样写程序。B调用A就是回调,底层API需要高层的代码来执行。

    最后,总结一下,回调方法的步骤:

    A类实现接口CallBack callback

    A类中包含了一个B的引用

    B中有一个参数为CallBack的方法f(CallBack callback)

    在A类中调用B的方法f(CallBack callback)——注册回调接口

    B就可以在f(CallBack callback)方法中调用A的方法——调用回调接口

    回调的例子

    我们以一个儿子在玩游戏,等妈妈把饭做好在通知儿子来吃为例,按照上面的步骤去写回调;

    上面的例子中,显然应该儿子来实现回调接口,母亲调用回调接口。所以我们先定义一个回调接口,然后让儿子去实现这个回调接口。

    其代码如下:

    public interface CallBack {

    void eat();

    }

    public class Son implements CallBack{

    private Mom mom;

    //A类持有对B类的引用

    public void setMom(Mom mom){

    this.mom = mom;

    }

    @Override

    public void eat() {

    System.out.println("我来吃饭了");

    }

    public void askMom(){

    //通过B类的引用调用含有接口参数的方法。

    System.out.println("饭做了吗?");

    System.out.println("没做好,我玩游戏了");

    new Thread(() -> mom.doCook(Son.this)).start();

    System.out.println("玩游戏了中......");

    }

    }

    然后我们还需要定义一个母亲的类,里面有一个含有接口参数的方法doCook

    public class Mom {

    //在含有接口参数的方法中利用接口参数调用回调方法

    public void doCook(CallBack callBack){

    new Thread(new Runnable() {

    @Override

    public void run() {

    try {

    System.out.println("做饭中......");

    Thread.sleep(5000);

    callBack.eat();

    } catch (InterruptedException e) {

    e.printStackTrace();

    }

    }

    }).start();

    }

    }

    我们通过一个测试类:

    public class Test {

    public static void main(String[] args) {

    Mom mom = new Mom();

    Son son = new Son();

    son.setMom(mom);

    son.askMom();

    }

    }

    这个例子就是典型的回调的例子。Son类实现了接口的回调方法,通过askMom这个方法调用Mom类中的doCook,实现注册回调接口,相当于A类中调用B类的代码C。在Mom类中的doCook来回调Son类中的eat,来告诉Son类中的结果。

    这样,我们就实现了一个简单的,符合定义的回调。

    回调例子的进一步探索

    我们主要看一下Son类的代码:

    public class Son implements CallBack{

    public Mom mom;

    public Son(Mom mom){

    this.mom = mom;

    }

    public void askMom(){

    System.out.println("饭做了吗?");

    System.out.println("没做好,我玩游戏了");

    new Thread(() -> mom.doCook(Son.this)).start();

    System.out.println("玩游戏了中......");

    }

    @Override

    public void eat() {

    System.out.println("好了,我来吃饭了");

    }

    }

    这个类里面,除了输出一些语句之外,真正有用的部分是mom.doCook(Son.this)以及重写eat方法。所以,我们可以通过匿名内部类的形式,简写这个回调。其代码如下:

    public class CallBackTest {

    public static void main(String[] args) {

    Mom mom = new Mom();

    new Thread(()-> mom.doCook(() -> System.out.println("吃饭了......"))).start();

    }

    }

    取消Son类,直接在主方法中通过匿名内部类去实现eat方法。其实匿名内部类就是回调的体现。

    异步回调与同步回调

    回调上面我们讲了 就是A调用B类中的方法C,然后在方法C里面通过A类的对象去调用A类中的方法D。

    我们在说一下异步与同步,先说同步的概念

    同步

    同步指的是在调用方法的时候,如果上一个方法调用没有执行完,是无法进行新的方法调用。也就是说事情必须一件事情一件事情的做,做完上一件,才能做下一件。

    异步

    异步相对于同步,可以不需要等上个方法调用结束,才调用新的方法。所以,在异步的方法调用中,是需要一个方法来通知使用者方法调用结果的。

    实现异步的方式

    在Java中最常实现的异步方式就是让你想异步的方法在一个新线程中执行。

    我们会发现一点,异步方法调用中需要一个方法来通知使用者调用结果,结合上面所讲,我们会发现回调方法就适合做这个事情,通过回调方法来通知使用者调用的结果。

    那异步回调就是A调用B的方法C时是在一个新线程当中去做的。

    上面的母亲通知儿子吃饭的例子,就是一个异步回调的例子。在一个新线程中,调用doCook方法,最后通过eat来接受返回值,当然使用lamdba优化之后的,本质是一样的。

    同步回调就是A调用B的方法C没有在一个新线程,在执行这个方法C的时候,我们什么都不能做,只能等待他执行完成。

    同步回调与异步回调的例子

    我们看一个Android中的一个同步回调的例子:

    button.setOnClickListener(new View.OnClickListener() {

    @Override

    public void onClick(View v) {

    Log.i("button","被点击");

    }

    });

    button通过setOnClickListener注册回调函数,和上面写的一样,通过匿名内部类的形式将接口的引用传进去。由于button调用setOnClickListener没有新建一个线程,所以这个是同步的回调。

    而异步回调,就是我们开篇讲的那个例子:

    call.enqueue(new Callback() {

    @Override

    public void onResponse(Call call, Response response) {

    HistoryBean hb = response.body();

    if(hb == null) return;

    showText.append(hb.isError() + "");

    for(HistoryBean.ResultsBean rb : hb.getResults()){

    showText.append(rb.getTitle() + "/n");

    }

    }

    @Override

    public void onFailure(Call call, Throwable t) {

    }

    });

    这个enqueue方法是一个异步方法去请求远程的网络数据。其内部实现的时候是通过一个新线程去执行的。

    通过这两个例子,我们可以看出同步回调与异步回调的使用其实是根据不同的需求而设计。不能说一种取代另一种,像上面的按钮点击事件中,如果是异步回调,用户点击按钮之后其点击效果不是马上出现,而用户又不会执行其他操作,那么会感觉很奇怪。而像网络请求的异步回调,因为受限于请求资源可能不存在,网络连接不稳定等等原因导致用户不清楚方法执行的时候,所以会用异步回调,发起方法调用之后去做其他事情,然后等回调的通知。

    回调方法在通信中的应用

    上面提到的回调方法,除了网络请求框架的回调除外,其回调方法都是没有参数,下面,我们看一下在回调方法中加入参数来实现一些通信问题。

    如果我们想要A类得到B类经过一系列计算,处理后数据,而且两个类是不能通过简单的将B的引用给A类就可以得到数据的。我们可以考虑回调。

    步骤如下:

    在拥有数据的那个类里面写一个回调的接口。-->这里就是B类中写一个回调接口

    回调方法接收一个参数,这个参数就是要得到的数据

    同样是在这个类里写一个注册回调的方法。

    在注册回调方法,用接口的引用去调用回调接口,把B类的数据当做参数传入回调的方法中。

    在A类中,用B类的引用去注册回调接口,把B类中的数据通过回调传到A类中。

    上面说的步骤,有点抽象。下面我们看一个例子,一个是Client,一个是Server。Client去请求Server经过耗时处理后的数据。

    public class Client{

    public Server server;

    public String request;

    //链接Server,得到Server引用。

    public Client connect(Server server){

    this.server = server;

    return this;

    }

    //Client,设置request

    public Client setRequest(String request){

    this.request = request;

    return this;

    }

    //异步发送请求的方法,lamdba表达式。

    public void enqueue(Server.CallBack callBack){

    new Thread(()->server.setCallBack(request,callBack)).start();

    }

    }

    public class Server {

    public String response = "这是一个html";

    //注册回调接口的方法,把数据通过参数传给回调接口

    public void setCallBack(String request,CallBack callBack){

    System.out.println("已经收到request,正在计算当中......");

    new Thread(() -> {

    try {

    Thread.sleep(5000);

    callBack.onResponse(request + response);

    } catch (InterruptedException e) {

    e.printStackTrace();

    callBack.onFail(e);

    }

    }).start();

    }

    //在拥有数据的那个类里面写一个接口

    public interface CallBack{

    void onResponse(String response);

    void onFail(Throwable throwable);

    }

    }

    接下来,我们看一下测试的例子:

    public class CallBackTest {

    public static void main(String[] args) {

    Client client = new Client();

    client.connect(new Server()).setRequest("这个文件是什么?").enqueue(new Server.CallBack() {

    @Override

    public void onResponse(String response) {

    System.out.println(response);

    }

    @Override

    public void onFail(Throwable throwable) {

    System.out.println(throwable.getMessage());

    }

    });

    }

    }

    结果如下:

    已经收到request,正在计算当中......

    这个文件是什么?这是一个html

    以上就是通过回调的方式进行通信

    展开全文
  • Java回调机制总结

    2021-02-12 10:07:23
    调用和回调机制在一个应用系统中, 无论使用何种语言开发, 必然存在模块之间的调用, 调用的方式分为几种:1.同步调用同步调用是最基本并且最简单的一种调用方式, 类A的方法a()调用类B的方法b(), 一直等待b()方法执行...
  • java调用回调机制详解

    2021-03-09 06:25:48
    调用和回调机制在一个应用系统中, 无论使用何种语言开发, 必然存在模块之间的调用, 调用的方式分为几种:1.同步调用同步调用是最基本并且最简单的一种调用方式, 类A的方法a()调用类B的方法b(), 一直等待b()方法执行...
  • Writer :BYSocket(泥沙砖瓦浆木匠)什么回调?...要先调用,才调用者和被调用者之间的回调。所以在百度百科中是这样的:软件模块之间总是存在着一定的接口,从调用方式上,可以把他们分为三类:同步...
  • Java回调机制

    2021-03-06 06:00:39
    最近一直在想罗振宇老师说的一段话,大致如下:任何一个行业都自己的独特性,你要是能将自己行业独有的认知模型质朴的语言讲述出来,让不是这个行业的人也能听懂,那么这个东西就价值连城。我自认为程序员真的是...
  • 继续探究Java回调函数

    2021-02-28 14:39:01
    回调函数是一个相当难以理解和...在C或者C++中回调函数的定义:程序在调用一个函数时,将自己的函数的地址作为参数传递给程序调用的函数时(那么这个自己的函数称回调函数)Java中没有指针,不能传递方法的地址,一般...
  • Java 线程回调

    2021-03-05 23:32:41
    同步回调与异步回调 上面的例子,可能人会提出这样的疑问: 这个例子需要用什么回调啊,使用同步调用的方式,学生对象回答完毕问题之后直接把回答的答案返回给老师对象不就好了? 这个问题的提出没有任何问题,...
  • java回调函数

    2021-03-06 19:38:23
    最近在学习Struts2,了解到过滤器和拦截器的不同,过滤器底层原理是基于回调方法,而拦截器是基于反射,然后递归感觉个通俗的解释:客户端和服务端作比喻,比如客户端A和服务端B,A向B发消息,发了之后,B处理消息要返回...
  • 举个例子所谓的回调,就是程序员A写了一段程序(程序a),其中预留有回调函数接口,并封装好了该程序。程序员B要让a调用自己的程序b中的一个方法,于是,他通过a中的接口回调自己b中的方法。举个例子:1. 首先定义一个...
  • java回调机制

    2021-03-01 09:25:10
    前几天看了一下Spring的部分源码,发现回调机制被大量使用,觉得必要把Java回调机制的理解归纳总结一下,以方便在研究类似于Spring源码这样的代码时能更加得心应手。注:本文不想扯很多拗口的话来充场面,我的目的...
  • java回调应用

    2021-03-01 06:48:55
    这个时候就可以使用回调了, 实现方法如下: 时间判断的地方的代码是: List stories = NewsBaiduParser.parse(html, isTitleOnly, includeWords,latestStoryTime ,new IFilter(){ public boolean filter(Story ...
  • 什么回调?一般来说,模块之间都存在一定的调用关系,从调用方式上看,可以分为三类:同步调用、异步调用和回调。同步调用是一种阻塞式调用,即在函数A的函数体里通过书写函数B的函数名来调用之,使内存中对应...
  • Java回调与反复

    2021-03-12 22:13:11
    什么回调?##先举个通俗易懂的例子经理要出差,给某个员工安排了任务(挖了个坑就不管了,员工你去填坑。这个坑就是回调),临走前吩咐,任务做完了记得通知我.定义回调规范CallBack/*** 约定一个消息(经理留下手机...
  • Java回调实现

    2021-02-28 19:16:47
    一。回调的形式1. C、C++和Pascal允许将函数指针作为参数传递给其它函数。...2. .NET Framework的语言中,提供了一...3. 使用匿名的代码块(lambda表达式),以代替在别处定义的独立的回调函数。4. 在缺少函数类型的参...
  • JAVA接口回调

    2021-03-09 18:22:36
    一:回调的用途回调一般用于层间协作,上层将本层函数安装在下层,这个函数...所谓的回调,就是程序员A写了一段程序(程序a),其中预留有回调函数接口,并封装好了该程序。程序员B要让a调用自己的程序b中的一个方法,...
  • Java接口回调

    2021-03-10 05:02:12
    回调的含义和用途什么回调?一般来说,模块之间都存在一定的调用关系,从调用方式上看,可以分为三类:同步调用、异步调用和回调。同步调用是一种阻塞式调用,即在函数A的函数体里通过书写函数B的函数名来调用之,...
  • 一、回调函数定义:首先说说什么回调函数?在WINDOWS中,程序员想让系统DLL调用自己编写的一个方法,于是利用DLL当中回调函数(CALLBACK)的接口来编写程序,使它调用,这个就 称为回调。在调用接口时,需要严格的...
  • 本文的目的并不是介绍使用的什么技术,而是重点阐述回调接口其实现原理。一、 异步和同步讲通俗点,异步就是不需要等当前执行的动作完成,就可以继续执行后面的动作。通常一个程序执行的顺序是:从上到下,依次执行...
  • 用Java回调(代码说明)

    2021-03-15 18:24:51
    但我不明白它对回调有什么用?>你能解释一下Java程序员的回调概念吗?码:public class Main {public interface Visitor {int DoJob(int a, int b);}public static void main(String[] args) {Visi...
  • 由于我发现很多项目中若是使用了回调的方式来实现功能,导致代码不易读,尤其是萌新很难看懂回调这种使用技巧,所以此一文。回调函数的demo案例如下:package com.jufanshare.demo;public class CallbackDemo {...
  • 深入理解java回调机制

    2021-03-06 22:02:45
    比如说android应用定义一个button对象,并给按钮添加一个监听事件,"onClick"方法就是常用的回调函数,用户触发该事件,android系统会自动调用该函数。目前最常见的说明就是:1.classA,classB2.classA实现接口...
  • 回调一直是一个JAVA中很重要的概念,应用场景:A.class需要使用B.class的方法,然后A还需要在B的方法执行完毕后,作出对应反应,即在B的方法中还需要回调到将它new出来的A的方法。为了方便理解,我们用到接口,做个...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 322,478
精华内容 128,991
关键字:

java的回调有什么应用

java 订阅