最近在学JAVA,以前用C的时候也会用到回调,但现在很少写代码了,所以看Android系统源码时对JAVA的回调总感觉没有切身的体会,总是没弄明白为什么要用回调,所以自己动手写了个小实例,切身体会一下在什么情况要要用到JAVA的回调
/*
** 小王打电话给小李,问1+1等于多少?
** 小李告诉小王,等于2
*/
public class CallBack {
public static void main(String[] args){
Wang w = new Wang();
w.askQuestion();
w.printResult();
}
}
public class Li {
public void dealQ(Wang w){
System.out.println("小王问我的问题是:"+w.Q1);
for (int i = 0; i < 100000; i++){
//思考中
System.out.println("正在思考………………");
}
String result = "2";
w.setResult(result);
}
}
public class Wang{
private String mResult;
public static String Q1 = "1+1=?";
public void askQuestion(){
Li l = new Li();
l.dealQ(this);
}
public void printResult(){
System.out.println("小李告诉我的答案是:" + mResult);
}
public void setResult(String result){
mResult = result;
}
}
上面的代码是按照我的思路写的,回头看看有两个问题:1.负责解决问题的小李,应该接收的是问题,而不是人;
所以把源码中的dealQ(Wang w)修改成dealQ(String question),另外因为小李不知道老王的存在,所以小李通过dealQ返回值给小王
public class Li {
public String dealQ(String question){
System.out.println("小王问我的问题是:"+question);
for (int i = 0; i < 10000; i++){
//思考中
System.out.println("正在思考………………");
}
String result = "3";
//w.setResult(result);
return result;
}
}
public class Wang{
private String mResult;
public static String Q1 = "1+2=?";
public void askQuestion(){
Li l = new Li();
setResult(l.dealQ(Q1));
}
public void printResult(){
System.out.println("小李告诉我的答案是:" + mResult);
}
public void setResult(String result){
mResult = result;
}
}
截止到这里,小王直接调用小李的回答接口,小王就知道答案了,好像也没有用到回调。我反复在想为什么没有用到回调呢,怎么才能用到回调呢,回头想想以前我用C写的回调都用在什么场景下的,好像回调都是用在带“触发”式的场合下的,然后瞬间就明白了,现在的程序还是过程化的,小王问问题,小李回答问题,小王拿到问题后告诉大家答案。如果我想做到,小王问小李问题,并告诉小李你算出答案后告诉告诉大家答案,我就不管了
就是让w.printResult();在小李算出答案时由小李触发调用。所以问题就变成要在小李里面调用printResult,所以自然想到通过接口来处理,另外小李对外的接口接收的就是问题和处理问题的方式:dealQ(handleResult handle, String question)
最终代码如下:
public class CallBack {
public static void main(String[] args){
Wang w = new Wang();
w.askQuestion();
}
}
public class Li {
public String dealQ(handleResult handle, String question){
System.out.println("小王问我的问题是:"+question);
for (int i = 0; i < 10000; i++){
//思考中
System.out.println("正在思考………………");
}
String result = "3";
handle.printResult(result);
return result;
}
}
public class Wang implements handleResult{
private String mResult;
public static String Q1 = "1+2=?";
public void askQuestion(){
Li l = new Li();
setResult(l.dealQ(this,Q1));
}
public void printResult(){
System.out.println("小李告诉我的答案是:" + mResult);
}
public void printResult(String result){
System.out.println("小王问题的答案是:" + result);
}
public void setResult(String result){
mResult = result;
}
}
public interface handleResult{
public void printResult(String result);
}
到这里基本上明白了用回调的来龙去脉,同时也发现了一个有趣的问题,我个人觉得这就是回调的价值所在。在最后小王调用小李的问题处理接口时传入的是l.dealQ(this,Q1),传入的参数是问题和问题的处理方式,但我们发现第一次的代码我们用的参数就是this,那应该第一次就解决这个问题了啊,没有后面两端优化的代码了,其实这两次的this不一样了,第一次的this代表的是小王这个人,第二次的this代表的只是小王要求得到答案后的处理方式。第一次小李知道小王所有的信息,但第二次小李只知道小王处理问题的方式。我觉得这个就是回调的价值所在。