【发布时间】:2013-10-16 13:57:08
【问题描述】:
我不明白什么是回调方法,而且我听说人们非常松散地使用该术语。在 Java 世界中,什么是回调方法?如果有人可以提供一些 Java 回调方法的示例代码并进行解释,那将对我的 Java 学习之旅有很大帮助。
【问题讨论】:
标签: java spring-mvc callback
我不明白什么是回调方法,而且我听说人们非常松散地使用该术语。在 Java 世界中,什么是回调方法?如果有人可以提供一些 Java 回调方法的示例代码并进行解释,那将对我的 Java 学习之旅有很大帮助。
【问题讨论】:
标签: java spring-mvc callback
回调是一段代码,您将其作为参数传递给其他代码,以便它执行它。由于 Java 还不支持函数指针,因此它们被实现为 Command 对象。类似的东西
public class Test {
public static void main(String[] args) throws Exception {
new Test().doWork(new Callback() { // implementing class
@Override
public void call() {
System.out.println("callback called");
}
});
}
public void doWork(Callback callback) {
System.out.println("doing work");
callback.call();
}
public interface Callback {
void call();
}
}
回调通常会持有对某些状态的引用以使其真正有用。
通过使回调实现对您的代码具有所有依赖关系,您可以在您的代码和执行回调的代码之间获得间接性。
【讨论】:
public class MyCallbackImpl implements Callback。
doWork() 方法中直接调用匿名类中的代码。
java 中的回调方法是在事件(称为E)发生时调用的方法。通常,您可以通过将某个接口的实现传递给负责触发事件E 的系统来实现它(参见示例1)。
同样在更大更复杂的系统中,您可以简单地注释一个方法,系统将识别所有注释的方法,并在事件发生时调用它们(参见示例 2)。当然,系统会定义该方法应该接收哪些参数以及其他约束。
示例 1:
public interface Callback {
//parameters can be of any types, depending on the event defined
void callbackMethod(String aParameter);
}
public class CallbackImpl implements Callback {
void callbackMethod(String aParameter) {
//here you do your logic with the received paratemers
//System.out.println("Parameter received: " + aParameter);
}
}
//.... and then somewhere you have to tell the system to add the callback method
//e.g. systemInstance.addCallback(new CallbackImpl());
示例 2:
//by annotating a method with this annotation, the system will know which method it should call.
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
public @interface CallbackAnnotation {}
public class AClass {
@CallbackAnnotation
void callbackMethod(String aParameter) {
//here you do your logic with the received paratemers
//System.out.println("Parameter received: " + aParameter);
}
}
//.... and then somewhere you have to tell the system to add the callback class
//and the system will create an instance of the callback class
//e.g. systemInstance.addCallbackClass(AClass.class);
【讨论】:
通过使用回调机制,我们将获得我们自己的方法实现只回调。或单击事件时的特定实现。 它主要用于java中的EventHandlers中。
package com.callbackExample;
public abstract interface SomeEventHandler {
public abstract void hadleClick();//by default abstract
}
package com.callbackExample;
public class SomeEventImplementation implements SomeEventHandler {
@Override
public void hadleClick() {
System.out.println("Click Handler : clicked");
}
}
package com.callbackExample;
public class Button {
public void onClick(SomeEventHandler clickEventHandler) {
clickEventHandler.hadleClick();
}
}
package com.callbackExample;
public class Test {
public static void main(String[] args) {
Button button=new Button();
SomeEventImplementation someEventImplementation=new SomeEventImplementation();
button.onClick(someEventImplementation);
Button button2=new Button();
button2.onClick(new SomeEventHandler() {
@Override
public void hadleClick() {
System.out.println("button2 : my own implementation..");
}
});
}
}
-------------------------------------------
OUTPUT : Click Handler : clicked
button2 : my own implementation..
-------------------------------------------
【讨论】:
简单来说,回调机制是指以另一个函数作为参数调用一个函数。在 C、C++ 等语言中,这是通过将函数指针作为参数传递来完成的,但 java 没有指针的概念。解决方法是接口。我们传递对接口的引用而不是指针。看完下面的代码,你的理解就会一清二楚。 为了展示真实世界的应用程序,想象一下购买鼠标和鼠标垫。鼠标垫价格是固定的,但鼠标价格因品牌而异。
interface mouse
{
double mousePrice();
}
class BrandA implements mouse
{
public double mousePrice() //note that public access modifier is needed as all methods of interface are public are by default and when you override them
//you cannot use any access modifier more restrictive
{
return 100;
}
}
class BrandB implements mouse
{
public double mousePrice()
{
return 200;
}
}
class Simple
{
static void total(mouse t)
{
double mousepad = 20;
double mousep = t.mousePrice();
System.out.println(mousepad + mousep);
}
public static void main(String args[])
{
mouse ob = new BrandA(); //upcasting.
total(ob);
}
}
【讨论】:
@Sotirios Delimanolis 的回答很好,但我想给出一个清晰的例子,以某种方式解释回调的侦听器如何工作 - android 库大量采用以下方法。
class RemoteClass {
private OnChangeListener mOnChangeListener;
void makeSomeChanges() {
/*
.. do something here and call callback
*/
mOnChangeListener.onChanged(this, 1);
}
public void setOnChangeListener(OnChangeListener listener) {
mOnChangeListener = listener;
}
public interface OnChangeListener {
public void onChanged(RemoteClass remoteClass, int test);
}
}
有一个类构建了我的某人,它的名称为 RemoteClass,并告诉您的类通过将 OnChangeListener 接口的实现传递给 setOnChangeListener 方法来引用回调。
class Test {
public static void main(String[] args) {
RemoteClass obj = new RemoteClass();
obj.setOnChangeListener(demoChanged);
obj.makeSomeChanges();
}
private static RemoteClass.OnChangeListener demoChanged = new RemoteClass.OnChangeListener() {
@Override
public void onChanged(RemoteClass remoteClass, int incoming) {
switch (incoming) {
case 1:
System.out.println("I will take appropriate action!");
break;
default:
break;
}
}
};
}
现在你的类已经完成了它的任务,RemoteClass 完成了它的工作,并在必要时调用makeSomeChanges 导致使用mOnChangeListener 引用执行onChanged 方法。
【讨论】: