我在Java中遇到了一个关于回调的问题。她的是运行的代码和最初的答案这里。
代码:
public class Main {
public interface Visitor {
int DoJob(int a, int b);
}
public static void main(String[] args) {
Visitor adder = new Visitor(){
public int DoJob(int a, int b) {
return a + b;
}
};
Visitor multiplier = new Visitor(){
public int DoJob(int a, int b) {
return a*b;
}
};
System.out.println(adder.DoJob(10, 20));
System.out.println(multiplier.DoJob(10, 20));
}
}
发布于 2010-10-28 09:37:06
我曾经写过一篇关于http://madhurtanwani.blogspot.com/2010/09/callbacks-in-java.html的小博客文章。希望能帮上忙!
在我尝试解释上面的代码后,我必须说,这不是最直观或最好的使用回调。我在文章中使用的示例是Collections.sort(),它清楚地引出了回调部分。
对于上面发布的代码,Neverthelss可以这样想:
Visitor
interface
实现上调用该interface
方法。调用方必须实现Visitor接口,并实现处理数据集的域特定逻辑。将处理从调用方委托回callee的部分称为使用interface
(契约规范)在Java中实现的回调。
发布于 2010-10-28 10:24:59
我不想在这里挑起火焰之战.但是回调的概念在C/C++、JavaScript、Python、可能是Ruby等语言中更容易理解。在这些语言中,回调只是一个函数指针。将函数作为此函数指针传递,其他代码将使用该指针调用您的函数。就这么简单。(请看维基百科的这个C示例)
但是Java没有函数指针,因此Java程序员需要使用匿名的内部类、接口和类似的东西,以便将函数封装在类中,并将该类的一个实例作为回调传递。
我想我已经回答了您的第二个问题(“您能向Java程序员解释回调的概念吗?”),但请参阅关于如何在Java中实现回调的其他答案。
发布于 2014-08-06 01:33:01
我以前是用Java开发的,直到我开始用C#及其委托进行编程,我才完全理解回调的概念。
这是因为正如@Denilson Sá完美地提到的那样,Java没有使用指向函数的指针。换句话说,在Java中,您可以调用一个方法并传递一些参数,例如原语值(int、long、char、boolean等)。和对象(字符串或任何类的任何实例,比如当您传递一个对象时,您基本上是在内存中的实际对象的内存中传递地址)。
Java中的回调概念可以通过使用接口并将它们(实现它们的对象)作为参数来实现。假设您有以下接口,该接口定义了任何类都必须作为ResultListener实现的方法。
interface ResultListener {
void onSuccessOperation(String description);
void onFailedOperation(String description);
}
现在假设您有一个在showScreen方法中运行的主程序
class MyMainScreen implements ResultListener {
public void showScreen() {
//do some things..
SmartClass smartClass = new SmartClass();
smartClass.divideAndNotify(5, 0, this);
}
public void onSuccessOperation(String description) {
System.out.println("SUCCESS!!. " + description);
}
public void onFailedOperation(String description) {
System.out.println("FAILED. " + description);
}
}
这就是知道如何分裂的SmartClass。
class SmartClass {
public void divideAndNotify(int numerador, int denominador, ResultListener resultListener) {
if (denominador == 0) {
resultListener.onFailedOperation("Nobody can divide by zero!!");
} else {
int total = numerador / denominador;
resultListener.onSuccessOperation("The result is " + total);
}
}
}
这里有趣的部分是,MyMainScreen作为一个ResultListener运行,因此它需要实现接口ResultListener中定义的方法。MyMainScreen知道如何在控制台上打印消息,但它对计算一无所知,这就是为什么它实例化SmartClass来使用它的方法divideAndNotify,该方法接受两个数字,并引用将侦听结果的实例(在本例中,这个实例是MyMainScreen实例本身,这就是为什么它与单词 this 一起传递自己的原因)。
SmartClass方法divideAndNotify知道数学,并将操作结果通知正在侦听的人。它的方法知道resultListener将包含对一个对象的引用,当结果成功或不成功时,该对象知道该做什么。
这里的回调概念是,SmartClass将功能委托给如何处理结果,就像在作为参数接收到的实例中的“回调”一样。
总结:回调只是一个任务的委托。
PS:对于C#,这个概念要简单得多,因为C#有委托类型,这些变量存储函数所在的内存地址(存储的函数必须与委托中定义的签名匹配)。
https://stackoverflow.com/questions/4041522
复制相似问题