Java中的回调接口是什么?

14

这段代码片段用于接口 SetObserver,取自Effective Java(避免过度同步第67项)

public interface SetObserver<E> {
// Invoked when an element is added to the observable set
void added(ObservableSet<E> set, E element);
}

而且SetObserver被传递给以下方法的addObserver()removeObserver()

// Broken - invokes alien method from synchronized block!
public class ObservableSet<E> extends ForwardingSet<E> {
  public ObservableSet(Set<E> set) {
    super(set);
  }

  private final List<SetObserver<E>> observers =
      new ArrayList<SetObserver<E>>();

  public void addObserver(SetObserver<E> observer) {
    synchronized (observers) {
      observers.add(observer);
    }
  }



  public boolean removeObserver(SetObserver<E> observer) {
    synchronized (observers) {
      return observers.remove(observer);
    }
  }



  private void notifyElementAdded(E element) {
    synchronized (observers) {
      for (SetObserver<E> observer : observers)
        observer.added(this, element);
    }
  }

Bloch将SetObserver<E>接口称为回调接口。在Java中,什么情况下会将一个接口称为回调接口?


1
可能是回调函数是什么?的重复。 - assylias
1
ObservableSet<E>不是一个接口,我想你的意思是SetObserver<E> - Alonso Dominguez
@Geek 我认为回调接口并没有什么特别之处。它们的定义和处理方式并没有什么特殊之处,这只是一个术语而已。我相信这是在Java中实现回调的唯一方式。首先了解一般的回调,然后再了解Java中的回调。 - Ozair Kafray
2
@Geek 回调是计算机科学中使用的一个非常通用的术语。当一段代码对某个事件感兴趣时,它会注册一个函数,以便在事件发生时调用该函数,从而使这段代码可以执行所需的操作。它不仅适用于JavaScript。在C/C++中有函数指针,在C#中有委托,在Java中我们使用接口来实现。 - Ozair Kafray
1
接口可以用于在Java中实现回调。回调是一种情况,您想传递对某些行为的引用,并让另一个对象稍后调用它。在C或C ++中,这是函数指针的主要领域。在Java中,我们使用接口代替。 - Lion
显示剩余4条评论
1个回答

19

"回调接口"作为一个界面的一般要求,需要提供一种让被调用者调用调用者代码的方式。主要思想是,调用者有一段需要在另一个组件的代码中发生某些情况时执行的代码。回调接口提供了一种将这段代码传递给被调用的组件的方法:调用者实现一个接口,被调用者调用其方法之一。

回调机制在不同语言中的实现可能不同:C# 除了回调接口外还有委托和事件,C语言有可以通过指针传递的函数,Objective C有代理协议等。但主要思想始终相同:调用者传递一段代码以在特定事件发生时调用它。


我可能错了,但在Java的情况下,说被调用者实现接口以便调用者可以回调它不是更正确吗?抱歉,我知道这个答案已经有将近3年的历史了。 - stevenelberger
1
@stevenelberger 我认为当前的描述是正确的:调用者实现一个接口,将该实现提供给被调用者,被调用者根据需要回调实现的方法。 - Sergey Kalinichenko

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接