一直搞不清楚~
一个类调用另一个类中的方法,前者称为调用者(caller)
,后者称为被调用者(callee)
,调用者就是发号施令的人,被调用者就是按要求执行命令的人。
通常,调用者需要做一件事情时,就会获取或创建一个被调用者的对象,然后调用它的方法,这是一种简单明了的关系,我们很容易就理解了。
而回调是这样一个过程:调用者那里事先有一些可能需要做的事情,被调用者把自己
注册到调用者那里,然后对他说:“有事叫我”,有点毛遂自荐的意思。然后当一件事情发生时,被调用者就会根据事先注册的情况调用合适的方法来处理。
例如,我们向按钮(调用者)注册了一个点击事件的处理程序(被调用者),当点击事件发生时按钮就会找到这些处理程序并调用它们。
回调特别适合于那种调用者事先不知道应该由哪些类来负责处理某件事的情况
例如,编写按钮类的人不知道别人应该怎么处理按钮的点击事件,但他又不能不给按钮添加事件,否则按钮就没法正常使用了呀,这时候他就可以通过回调来解决这件事。
发现你最近也有提Android相关的问题,那我就通过Android ListView item的点击事件,一种使用频率很高的view,通过它认识“回调”,可能有助于理解。
比如ListView包含几个概略信息条目,你想点击某个条目跳到详情界面。
一般需要这样做:
mListView.setOnItemClickListener(mOnItemClickListener);
private OnItemClickListener mOnItemClickListener = new OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
Intent intent = new Intent(getActivity(), DetailActivity.class);
intent.putExtra(DetailActivity.ITEM_ID, position);
startActivity(intent);
}
};
当你这样做时,就已经实现了一个回调(implements a callback interface)。
接下来发生的事情我们就知道了,点某个条目就跳到其详情界面。
问题是,谁去调(call)它呢?我们在实现(implements)这个回调时,为什么必须要override其中的方法呢?
为了厘清这个问题,我们从点击事件发生时执行的代码看起:
// AdapterView.class, 这是ListView父类的父类
// 当view被点到时,performItemClick就被调到,处理点击带给view的变化,除此之外,
// AdapterView还想到了,“如果其它类想在点击发生时做点儿事情,该怎么办呢?”
// 通过接口。
// (1)我来定义接口,把知道的信息(被点到的view、position、id)告诉你;
// (2)你来实现接口,然后把实现的接口告诉我。
// 呐,这是我定义的接口。
255 public interface OnItemClickListener {
270 void onItemClick(AdapterView<?> parent, View view, int position, long id);
271 }
// 呐,你通过这个方法把实现的接口告诉我,我会存起来的。
279 public void setOnItemClickListener(OnItemClickListener listener) {
280 mOnItemClickListener = listener;
281 }
134 OnItemClickListener mOnItemClickListener;
// 那么现在点击事件发生了:
302 public boolean performItemClick(View view, int position, long id) {
// 我先检查你是否实现了接口;
303 if (mOnItemClickListener != null) {
// 嘿,该你回来做事情了。这就是callback,我call,你back。
305 mOnItemClickListener.onItemClick(this, view, position, id);
309 return true;
310 }
312 return false;
313 }
android.widget.AdapterView 源码链接
这是callback一种典型的应用场景。Android中有很多OnClickListener使用场景,看多了之后才对callback有些粗浅的认识,以前也是糊里糊涂的。
还有其它一些注册接口的形式,比如:register***Callbacks
, unregister***Callbacks
, remove***Callbacks
。
就是这样 :)
Java是面向对象的,不存在回调函数这个说法。
回调函数是脚本语言之类的叫法,作为参数传递,在某个事件发生时执行的函数叫做回调函数。
function doSomething(finishCallBack){
// 做事
// 做完,调事件完成的回调函数。
finishCallBack();
}
java能把方法作为参数传递吗?不能, 但是java有很多类似的机制可以实现这种所谓的“回调”,比如匿名内部类:
public interface FinishHandler{
public void afterFinish();
}
public class SomeTask{
public void doSomething(FinishHandler handler){
// 做事
handler.afterFinish(); // "回调"
}
}
new SomeTask().doSomething(new FinishHandler(){
public void afterFinish(){
System.out.println("事情做完咯~~~")
}
});
3 回答2.6k 阅读✓ 已解决
3 回答4.1k 阅读✓ 已解决
8 回答3.8k 阅读
4 回答2.8k 阅读✓ 已解决
2 回答2.7k 阅读✓ 已解决
3 回答2.6k 阅读✓ 已解决
4 回答1.9k 阅读
回调就是一种利用函数指针进行函数调用的过程. 通过回调,对象能够携带一些信息,这些信息允许它在稍后的某个时刻调用初始的对象。回调的价值在于它的灵活性,可以在运行时动态的决定需要调用什么方法。引用一段话:
java的内部类实现了回调机制,在java的GUI中到处可以看到回调的例子。
详细查看:java编程思想第10章,提到了闭包和回调。Java8引入Lambda表达式,也是使用匿名内部类实现类似回调的机制。