Home > Java > javaTutorial > body text

A wonderful explanation of the callback mechanism in Java (CallBack)

高洛峰
Release: 2017-01-24 13:25:26
Original
1395 people have browsed it

Preface

I recently learned Java and came into contact with the callback mechanism (CallBack). It felt quite confusing when I first met it, and the relevant explanations I searched on the Internet were either given in one sentence, or they were relatively simple and seemed to provide a definition for CallBack. Of course, after I understood the callbacks, I went to read various explanations on the Internet, and there was really no problem. However, for me as a beginner, there is a step-by-step process missing.

Callback is a two-way calling mode. What does it mean? That is, the callee will also call the other party when it is called. This is called a callback. "If you call me, I will call back."

Don’t understand? It doesn't matter, let's take a look at this arguably more classic way of using callbacks:

class A implements the interface InA - Background 1

class A contains a class B Reference b - Background 2

class B has a method test(InA a) with a parameter of InA - Background 3

A's object a calls B's The method passes in itself, test(a) - this step is equivalent to you call me

Then b can call InA's method in the test method - this step is equivalent to i call you back

Before you begin, imagine a scene: Kindergarten children have just learned addition within 10.

Below, I will describe my personal understanding of the callback mechanism in order from shallow to deep. If there is anything wrong, please feel free to enlighten me!

Chapter 1. The origin of the story

The kindergarten teacher wrote an equation "1 + 1 =" on the blackboard, and Xiao Ming filled in the blanks.

Since he has learned addition within 10, Xiao Ming can calculate this problem completely by himself. The code to simulate the process is as follows:

public class Student
 {
  private String name = null;
 
  public Student(String name)
  {
   // TODO Auto-generated constructor stub
   this.name = name;
  }
 
  public void setName(String name)
  {
   this.name = name;
  }
 
  private int calcADD(int a, int b)
  {
   return a + b;
  }
 
  public void fillBlank(int a, int b)
  {
   int result = calcADD(a, b);
   System.out.println(name + "心算:" + a + " + " + b + " = " + result);
  }
 }
Copy after login

When Xiao Ming fills in the blanks (fillBalnk), I did some mental arithmetic (clacADD) and found that the result is 2, and wrote the result in the blank box. The test code is as follows:

public class Test
 {
  public static void main(String[] args)
  {
  int a = 1;
   int b = 1;
   Student s = new Student("小明");
   s.fillBlank(a, b);
  }
 }
Copy after login

The running results are as follows:

Xiao Ming’s mental arithmetic: 1 + 1 = 2

This process is completely completed by the instance object of the Student class alone, and does not involve the callback mechanism.

Chapter 2. The Kindergarten Teacher's Finding Trouble

During the break, the kindergarten teacher had a sudden idea and wrote "168 + 291 =" on the blackboard for Xiao Ming to complete, and then returned to the office.

花刀! Why do all the teachers have trouble with Xiao Ming? It's obviously over the top, okay! At this time, it was obvious that Xiao Ming could no longer rely on mental arithmetic as above. When he was confused, Xiao Hong, a classmate in the class, handed over a calculator that could only calculate addition (profiteer)! ! ! ! Xiao Ming happened to know how to use a calculator, so he used the calculator to calculate the results and fill in the blanks.

The code of the calculator is:

public class Calculator
 {
  public int add(int a, int b)
  {
   return a + b;
  }
 }
Copy after login

Modify the Student class and add the method of using the calculator:

public class Student
 {
  private String name = null;
 
  public Student(String name)
  {
   // TODO Auto-generated constructor stub
   this.name = name;
  }
 
  public void setName(String name)
  {
   this.name = name;
  }
 
  @SuppressWarnings("unused")
  private int calcADD(int a, int b)
  {
   return a + b;
  }
 
  private int useCalculator(int a, int b)
  {
   return new Calculator().add(a, b);
  }
 
  public void fillBlank(int a, int b)
  {
   int result = useCalculator(a, b);
   System.out.println(name + "使用计算器:" + a + " + " + b + " = " + result);
  }
 }
Copy after login

The test code is as follows:

public class Test
 {
  public static void main(String[] args)
  {
   int a = 168;
   int b = 291;
   Student s = new Student("小明");
   s.fillBlank(a, b);
  }
 }
Copy after login

The running results are as follows:

Xiao Ming uses calculation Calculator: 168 + 291 = 459

This process still does not involve the callback mechanism, but some of Xiao Ming’s work has been transferred and is assisted by the calculator.

3. The kindergarten teacher came back and found that Xiao Ming had completed the addition of three digits. The teacher thought that Xiao Ming was very smart and a malleable talent. So he wrote "26549 + 16487 = " on the blackboard and asked Xiao Ming to fill in the blanks before going to class, and then returned to the office.

Xiao Ming looked at the friends having fun outside the classroom and couldn't help feeling sad. If we don’t go out to play, this recess will be ruined! ! ! ! Looking at the calculator that Xiao Hong handed over again, Xiao Ming came up with a plan: let Xiao Hong do it for her.

Xiao Ming told Xiao Hong that the topic was "26549 + 16487 = ", then pointed out the specific location where the result should be filled in, and then went out to play happily.

Here, we do not implement Xiaohong separately, but consider this calculator that can only perform addition and Xiaohong as a whole, a super calculator that can calculate results and fill in the blanks. The parameters that need to be passed to this super calculator are two addends and the positions to be filled in, and these contents need to be informed by Xiao Ming in advance, that is, Xiao Ming wants to expose part of his method to Xiao Hong. The simplest way is to Tell Xiaohong the quote and the two addends.

Therefore, the add method of the super calculator should contain two operands and a reference to Xiao Ming himself. The code is as follows:

public class SuperCalculator
 {
  public void add(int a, int b, Student xiaoming)
  {
   int result = a + b;
   xiaoming.fillBlank(a, b, result);
  }
 }
Copy after login

Xiao Ming’s Bian no longer needs mental arithmetic or a calculator, so he only needs a way to ask Xiaohong for help. The code is as follows:

public class Student
 {
  private String name = null;
 
  public Student(String name)
  {
   // TODO Auto-generated constructor stub
   this.name = name;
  }
 
  public void setName(String name)
  {
   this.name = name;
  }
 
  public void callHelp (int a, int b)
  {
   new SuperCalculator().add(a, b, this);
  }
 
  public void fillBlank(int a, int b, int result)
  {
   System.out.println(name + "求助小红计算:" + a + " + " + b + " = " + result);
  }
 }
Copy after login

The test code is as follows:

public class Test
 {
  public static void main(String[] args)
  {
   int a = 26549;
   int b = 16487;
   Student s = new Student("小明");
   s.callHelp(a, b);
  }
 }
Copy after login

The running result is:


Xiao Ming asks Xiao Hong for help to calculate: 26549 + 16487 = 43036


The execution process is: Xiao Ming calls the add method of Xiao Hong (new SuperCalculator()) through his own callHelp method, and passes in his own reference (this) as a parameter when calling. , after Xiaohong used the calculator to get the result, she called back Xiaoming's fillBlank method and filled the result in the blank space on the blackboard.

Light, light, light! At this point, the callback function officially appears. Xiao Ming's fillBlank method is what we often call the callback function.

通过这种方式,可以很明显的看出,对于完成老师的填空题这个任务上,小明已经不需要等待到加法做完且结果填写在黑板上才能去跟小伙伴们撒欢了,填空这个工作由超级计算器小红来做了。回调的优势已经开始体现了。

第4章. 门口的婆婆

幼稚园的门口有一个头发花白的老婆婆,每天风雨无阻在那里摆着地摊卖一些快过期的垃圾食品。由于年纪大了,脑子有些糊涂,经常算不清楚自己挣了多少钱。有一天,她无意间听到了小明跟小伙伴们吹嘘自己如何在小红的帮助下与幼师斗智斗勇。于是,婆婆决定找到小红牌超级计算器来做自己的小帮手,并提供一包卫龙辣条作为报酬。小红经不住诱惑,答应了。

回看一下上一章的代码,我们发现小红牌超级计算器的add方法需要的参数是两个整型变量和一个Student对象,但是老婆婆她不是学生,是个小商贩啊,这里肯定要做修改。这种情况下,我们很自然的会想到继承和多态。如果让小明这个学生和老婆婆这个小商贩从一个父类进行继承,那么我们只需要给小红牌超级计算器传入一个父类的引用就可以啦。

不过,实际使用中,考虑到java的单继承,以及不希望把自身太多东西暴漏给别人,这里使用从接口继承的方式配合内部类来做。

换句话说,小红希望以后继续向班里的小朋友们提供计算服务,同时还能向老婆婆提供算账服务,甚至以后能够拓展其他人的业务,于是她向所有的顾客约定了一个办法,用于统一的处理,也就是自己需要的操作数和做完计算之后应该怎么做。这个统一的方法,小红做成了一个接口,提供给了大家,代码如下:

public interface doJob
 {
  public void fillBlank(int a, int b, int result);
 }
Copy after login

因为灵感来自帮小明填空,因此小红保留了初心,把所有业务都当做填空(fillBlank)来做。

同时,小红修改了自己的计算器,使其可以同时处理不同的实现了doJob接口的人,代码如下:

public class SuperCalculator
 {
  public void add(int a, int b, doJob customer)
  {
   int result = a + b;
   customer.fillBlank(a, b, result);
  }
 }
Copy after login

小明和老婆婆拿到这个接口之后,只要实现了这个接口,就相当于按照统一的模式告诉小红得到结果之后的处理办法,按照之前说的使用内部类来做,代码如下:
小明的:

public class Student
 {
  private String name = null;
 
  public Student(String name)
  {
   // TODO Auto-generated constructor stub
   this.name = name;
  }
 
  public void setName(String name)
  {
   this.name = name;
  }
 
  public class doHomeWork implements doJob
  {
 
   @Override
   public void fillBlank(int a, int b, int result)
   {
    // TODO Auto-generated method stub
    System.out.println(name + "求助小红计算:" + a + " + " + b + " = " + result);
   }
 
  }
 
  public void callHelp (int a, int b)
  {
   new SuperCalculator().add(a, b, new doHomeWork());
  }
 }
Copy after login

老婆婆的:

public class Seller
{
 private String name = null;
 
 public Seller(String name)
 {
  // TODO Auto-generated constructor stub
  this.name = name;
 }
 
 public void setName(String name)
 {
  this.name = name;
 }
 
 public class doHomeWork implements doJob
 {
 
  @Override
  public void fillBlank(int a, int b, int result)
  {
   // TODO Auto-generated method stub
   System.out.println(name + "求助小红算账:" + a + " + " + b + " = " + result + "元");
  }
 
 }
 
 public void callHelp (int a, int b)
 {
  new SuperCalculator().add(a, b, new doHomeWork());
 }
}
Copy after login

测试程序如下:

public class Test
{
 public static void main(String[] args)
 {
  int a = 56;
  int b = 31;
  int c = 26497;
  int d = 11256;
  Student s1 = new Student("小明");
  Seller s2 = new Seller("老婆婆");
 
  s1.callHelp(a, b);
  s2.callHelp(c, d);
 }
}
Copy after login

   

运行结果如下:

小明求助小红计算:56 + 31 = 87

老婆婆求助小红算账:26497 + 11256 = 37753元

总结

可以很明显的看到,小红已经把这件事情当做一个事业来做了,看她给接口命的名字doJob就知道了。

有人也许会问,为什么老婆婆摆摊能挣那么多钱? 你的关注点有问题好吗!!这里聊的是回调机制啊!!

我只知道,后来小红的业务不断扩大,终于在幼稚园毕业之前,用挣到的钱买了人生的第一套房子。

以上就是本文对于Java中的回调机制(CallBack) 的有趣详解,希望给大家学习java有所帮助。也谢谢大家对PHP中文网的支持。

更多妙解Java中的回调机制(CallBack)相关文章请关注PHP中文网!

Related labels:
source:php.cn
Statement of this Website
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn
Popular Tutorials
More>
Latest Downloads
More>
Web Effects
Website Source Code
Website Materials
Front End Template
About us Disclaimer Sitemap
php.cn:Public welfare online PHP training,Help PHP learners grow quickly!