Link: https://www.zhihu.com/question/19801131/answer/26586203
Source: Know
Preface
Among the various open source tools in the Java community, callback methods are widely used. Therefore, familiarity with callback methods can undoubtedly accelerate their mastery of open source wheels.
Some articles have been searched on the Internet, but the introduction of callback methods mostly stays at the level of what callback methods are. This article attempts to introduce how callback methods come into being, why callback methods should be used and how to use them in actual projects.
Whether the scene is chosen properly or not has a great impact on the reader's interest in continuing to read and even the initiative of understanding (as a long-term Internet technology blog reader, I have deep feelings).
Good scenes are self-evident: familiar and simple.
The scenario carefully chosen for this example is: homework. (hope you like)
Write yourselfNote: There are at least three aspects of homework writing: who, what action (writing) and what to write.
Let's start with (a student, writing, homework).
# 1. There is a student. Student student = new Student(); # 2. The student has homework to do. student.doHomeWork(someHomeWork); # 3. Notice that this homework action needs to be included"task"Later on. So for this student new A simple topic to do. String aHomeWork = "1+1=?"; student.doHomeWork(aHomeWork);
So far, finish the homework.
Complete code
public class Student { public void doHomeWork(String homeWork) { System.out.println("Exercise book"); if("1+1=?".equals(homeWork)) { System.out.println("Homework:"+homeWork+" Answer:"+"2"); } else { System.out.println("Homework:"+homeWork+" Answer:"+"Hear nothing of~~"); } } public static void main(String[] args) { Student student = new Student(); String aHomeWork = "1+1=?"; student.doHomeWork(aHomeWork); } }
program execution
Exercise book Assignment: 1 + 1=? Answer: 2
We must focus on the need for homework.
The students'method of writing homework is ready-made, but they need homework as their participation. How to get homework is the key to complete the action. I hope this can be deeply impressed in our minds.
Ask roommates to help answer
In the example above, the student calls his own method and writes directly the homework he receives.
But in reality, there may be a variety of problems that make it impossible for the student to do it by himself. For example, he wants to play games or have a date. So he asked his roommate to help write it down. How to achieve it?
#1. Because roommates help write,So in doHomeWork Action inside,There is no need for logical judgment code,Because roommates will write in the answers directly.. Change to: student.doHomeWork(aHomeWork, theAnswer); #Action support for homework in the previous sentence is introduced"task"and"Answer",With these two,That means you can do your homework well.. #among aHomeWork Jobs are known,however theAnswer The answer is provided by roommates.. #How can roommates provide answers?,The simplest is,Roommate This object directly provides an incoming job,Ways to get the answer out,In this way, the student can call directly.. RoomMate roomMate = new RoomMate(); String theAnswer = roomMate.getAnswer(aHomeWork); student.doHomeWork(aHomeWork, theAnswer);
Complete code
public class Student { public void doHomeWork(String homeWork, String answer) { System.out.println("Exercise book"); if(answer != null) { System.out.println("Homework:"+homeWork+" Answer:"+ answer); } else { System.out.println("Homework:"+homeWork+" Answer:"+ "(blank)"); } } public static void main(String[] args) { Student student = new Student(); String aHomeWork = "1+1=?"; RoomMate roomMate = new RoomMate(); String theAnswer = roomMate.getAnswer(aHomeWork); student.doHomeWork(aHomeWork, theAnswer); } }
public class RoomMate { public String getAnswer(String homework) { if("1+1=?".equals(homework)) { return "2"; } else { return null; } } }
program execution
Exercise book Assignment: 1 + 1=? Answer: 2
Anger, a good way to call back~~
So far, there is no need to use the callback method.
Technology always comes with new demands.
Okay, give you new needs.
Here comes the point.
Let's review these two lines of code
#Roommates do their homework well String theAnswer = roomMate.getAnswer(aHomeWork); #The student copied the answer directly.,finish one's homework student.doHomeWork(aHomeWork, theAnswer);
The student thought for a moment, you gave the answer to the fart, but also I have to transcribe it to the homework book (to carry out their own methods of doing homework).
You can't call my homework method directly to help me write the answer and finish the homework.
Unable to withstand the students'soft grinding, the "good roommate of China" agreed. How to achieve it?
Review the whole process of homework
#Work to be solved String aHomeWork = "1+1=?"; #Roommates write answers String theAnswer = roomMate.getAnswer(aHomeWork); #The student calls,Write your answers in your homework. (That is to say, this step is not called.) student.doHomeWork(aHomeWork, theAnswer); #You have to call this method to do your homework.,This method must be invoked by roommates on demand.. That's obvious.,The roommate has to keep a quotation from the classmate.,Can normal call ah. #Lamp lamp~ #Roommate said,So you're calling getAnswer Method time,In addition to incoming jobs,You also need to put your own quotations in it.. So I'm done.,Just call your homework method directly.. roomMate.getAnswer(aHomeWork,student);
Complete code
public class Student { public void doHomeWork(String homeWork, String answer) { System.out.println("Exercise book"); if(answer != null) { System.out.println("Homework:"+homeWork+" Answer:"+ answer); } else { System.out.println("Homework:"+homeWork+" Answer:"+ "(blank)"); } } public static void main(String[] args) { Student student = new Student(); String aHomeWork = "1+1=?"; RoomMate roomMate = new RoomMate(); roomMate.getAnswer(aHomeWork,student); } }
public class RoomMate { public void getAnswer(String homework, Student student) { if("1+1=?".equals(homework)) { student.doHomeWork(homework, "2"); } else { student.doHomeWork(homework, "(blank)"); } } }
Execution procedure
Exercise book Assignment: 1 + 1=? Answer: 2
callback
In the above example of "letting roommates write their homework directly", in fact, the meaning of callback has been embodied.
The core of the scene is that the student has to do his homework.
Simple Description: The student told his roommate what homework to do and gave his quotation to his roommate. The roommate gets the homework, quotes the student directly after doing it and calls the method of doing homework to complete the task of writing homework on behalf of the student.
A slightly more complex description:
There are two ways for the student to do his homework. One is the homework topic (known) and the other is the homework answer (unknown).
Roommates provide a way to help him with his homework. This method has two entries, one is the homework title, the other is the student's quotation (to solve the answer to know where to write).
When the program is executed, the student only needs to call the roommate's proxy homework method. Once the roommate gets the answer, because the student quotes, so directly find the corresponding method to help them complete their homework.
More complex point description:
Students call their roommates'homework methods and register the title and their own citations. When the roommate's alternative homework method is called, he will finish his homework according to the topic, and then call back the student's homework method to finish the homework.
Then the abstract point description:
Class A calls method B of class B (passing in relevant information). After the method of class B is executed, the result will be written to method a of class A (callback) to complete the action. (Actually method a is the legendary callback method.)
The most abstract description:
Call back.
Callback method of interface mode
Students who often use callback methods may say that I have never seen an object reference written directly into the first invocation method.
Well, yes, let's fill in the "heavenly pit" left by the above examples (often seen in actual projects).
Question: What's wrong with passing object references directly into invocation methods?
Just to say a little, just let others write a way for them. Do you have to expose yourself to others? What if the other person is the competitor's interface? Is this the legendary latter code (/ tx).
Anyway, it's very unsafe to do so.
Therefore, the most common implementation of Callback is (as you have guessed) to use interfaces as references (which are not rigorous) to pass into the method of invocation.
I admit that it took me a long time to jump from thinking to using interfaces.
Let's look at the getAnswer method of the RoomMate class.
public class RoomMate { public void getAnswer(String homework, Student student) { if("1+1=?".equals(homework)) { student.doHomeWork(homework, "2"); } else { student.doHomeWork(homework, "(blank)"); } } }
The key is that this method is used to solve a problem raised by a student. The answer is sent back through the student's doHomeWork method. Assuming that a worker has a problem, how can the roommate solve it? Another way to receive references from workers? Of course not, as long as your reference contains the doHomeWork() method, then whether you are a worker, a policeman or a sanitation worker, call the getAnswer() method directly to solve your problem.
So far, our idea has come to the conclusion that all objects have the same method, so the concept of interface is introduced by self-heating. As long as these objects implement an interface, the function of this interface is only to specify what the method of doing homework looks like. In this way, the worker implements the interface, and then there is a default inheritance of the method of doing work. When the worker throws his quotation to the roommate again, the roommate does not need to change any code, contacts the answer directly, and completes the task.
Create an interface for doing homework, specifying what you need (questions and answers) to do your homework.
public interface DoHomeWork { void doHomeWork(String question, String answer); }
Change the Chinese roommate's answer. Any person who implements the DoHomeWork interface has a method of doHomeWork(String question,String answer). This method is the "callback method" mentioned above. Somone calls his roommate's getAnswer() method first, and passes in the question and himself (this is called). After his roommate answers the question, he calls the default method and writes his homework.
Think about it, because the Convention is that the interface is used as a parameter type. After upcast is upcast, the method described by the interface will only be exposed. Others can only use this (callback) method when they get this reference. So far, the major security risks left behind have been solved.
Complete code
public class RoomMate { public void getAnswer(String homework, DoHomeWork someone) { if("1+1=?".equals(homework)) { someone.doHomeWork(homework, "2"); } else { someone.doHomeWork(homework, "(blank)"); } } }
package org.futeng.designpattern.callback.test1; public class Worker implements DoHomeWork { @Override public void doHomeWork(String question, String answer) { System.out.println("Exercise book"); if(answer != null) { System.out.println("Homework:"+question+" Answer:"+ answer); } else { System.out.println("Homework:"+question+" Answer:"+ "(blank)"); } } public static void main(String[] args) { Worker worker = new Worker(); String question = "1+1=?"; new RoomMate().getAnswer(question, worker); } }
Execution procedure
Exercise book Assignment: 1 + 1=? Answer: 2
So far, is the article calling + callback finished?
Cough, there's nothing left. Let's have some tea and bear with it. (I've been writing for a day -)
Anonymous Internal Classes for Conventional Use
As ordinary farts, pragmatism is the survival principle we adhere to.
Therefore, all the technologies that are not needed can be avoided, and all the technologies that are learned but not used are equal to learning in vain.
We have qualitatively identified that Chinese roommate RoomMate class has the potential to accept any challenge from anyone.
Since a good roommate became famous, someone who didn't know what kind of job (type) was asking questions. Anyway, as long as the callback interface is implemented, good roommates can call the callback method that you inherit by default, so let's go.
package org.futeng.designpattern.callback.test1; public class RoomMate { public void getAnswer(String homework, DoHomeWork someone) { if("1+1=?".equals(homework)) { someone.doHomeWork(homework, "2"); } else { someone.doHomeWork(homework, "(blank)"); } } public static void main(String[] args) { RoomMate roomMate = new RoomMate(); roomMate.getAnswer("1+1=?", new DoHomeWork() { @Override public void doHomeWork(String question, String answer) { System.out.println("Question:"+question+" Answer:"+answer); } }); } }
See a slightly strange line of roomMate. getAnswer ("1 + 1=?"), new DoHomeWork () {which line, in fact, here is an anonymous inner class of the DoHomeWork interface. Here I think you should think for yourself, call + inversion, how this process is achieved.
The use of anonymous inner classes is determined by the specific usage scenario. Ordinary classes are not direct enough, and the grammar of anonymous inner classes seems not friendly enough.
The above examples of anonymous inner classes are common usage patterns in open source tools.
Call the method of roomMate to solve the problem (pass in your own reference), roomMate to solve the problem, call back the callback method contained in the reference, complete the action.
roomMate is a tool class. You pass in two parameters (and more importantly, it makes sense) to invoke the method. It's all right to put the problem where it's solved. When the "call" method finds the answer to the question, it writes the result to the location you specified (as a reference to the callback method).
Imagine that the problem that "Chinese good roommate" receives is the SQL statement. The place where the receipt is placed is my reference. You solve the problem (execute the SQL), and write the answer (the feedback result of the SQL) directly into my callback method. The callback method may include a field assignment. But there are many details hidden at the call level. This is a small advantage of the callback method. In other words, you don't need to get the returned results after the execution of the SQL to assign values one by one.
Examples of SQL
public static List<Person> queryPerson() { QueryRunner queryRunner = new QueryRunner(DataSourceSupport.getDataSource()); return queryRunner.query(" select t.name, t.age from person t ", new ResultSetHandler<List<Person>>(){ List list = new ArrayList<Person>(); @Override public List<Person> handle(ResultSet rs) throws SQLException { while(rs.next()) { Person person = new Person(); person.setName(rs.getString(0)); person.setAge(rs.getInt(1)); list.add(person); } return list; } }); }
Advantages of callback methods
The greatest advantage of callback method is asynchronous callback, which is the reason why it is most widely used.
Next, we will use "Chinese good roommate" to implement the callback asynchronously.
Callback interface need not be changed
public interface DoHomeWork { void doHomeWork(String question, String answer); }
In order to reflect the meaning of asynchrony, we set up a difficult problem for our good roommates, hoping that they can have more time to think.
Student student = new Student(); String homework = "When x Tending to zero, sin(x)/x =?"; #Build a new one for students ask Method,Another thread is opened in this method.,Waiting for the result feedback of the callback method. student.ask(homework, new RoomMate()); #ask The method is as follows public void ask(final String homework, final RoomMate roomMate) { new Thread(new Runnable() { @Override public void run() { roomMate.getAnswer(homework, Student.this); } }).start(); goHome(); } #New threads are simply used to wait for good roommates to finish writing.. Because the waiting time of 3 seconds is set in the good roommate class,So you can see goHome Method will be executed first. #It means that the student is informed of his roommate's role.,You can do your own thing.,No synchronous blocking is required to wait for results. #Once a good roommate completes his role,Write to the workbook,The site is finished..
Complete code
public class Student implements DoHomeWork{ @Override public void doHomeWork(String question, String answer) { System.out.println("Exercise book"); if(answer != null) { System.out.println("Homework:"+question+" Answer:"+ answer); } else { System.out.println("Homework:"+question+" Answer:"+ "(blank)"); } } public void ask(final String homework, final RoomMate roomMate) { new Thread(new Runnable() { @Override public void run() { roomMate.getAnswer(homework, Student.this); } }).start(); goHome(); } public void goHome(){ System.out.println("I went home... Good roommate, help me write down my homework."); } public static void main(String[] args) { Student student = new Student(); String homework = "When x Tending to zero, sin(x)/x =?"; student.ask(homework, new RoomMate()); } }
public class RoomMate { public void getAnswer(String homework, DoHomeWork someone) { if ("1+1=?".equals(homework)) { someone.doHomeWork(homework, "2"); } else if("When x Tending to zero, sin(x)/x =?".equals(homework)) { System.out.print("Reflection:"); for(int i=1; i<=3; i++) { System.out.print(i+"second "); try { TimeUnit.SECONDS.sleep(1); } catch (InterruptedException e) { e.printStackTrace(); } } System.out.println(); someone.doHomeWork(homework, "1"); } else { someone.doHomeWork(homework, "(blank)"); } } }
So far, the introduction of callback method has come to an end.