Tuesday, May 15, 2007

Callbacks in Java

Unlike most other languages that provide function pointers in some form or other, Java doesn't. So the next question leading up is what's the workaround?
Ans. Event handlers or interfaces

Java or any other language that supports inheritance makes it possible to define something called an interface (abstract class with only pure virtual functions in c++).




Java
public interface Callback {
  public void fn();
}

C++
class callback {
public:
  virtual void fn() = 0;
}




so when we want to create a callback function we implement this interface, with the function 'fn' in this example being defined in the derived class. This function then becomes your callback.

Java

public class CallbackHandler implements Callback {
  public void fn() {
    // your implementation goes here
  }
}

public class SomeClass {
  public void foo() {
    EventGenerator event = new EventGenerator();
    // we're creating an instance of the callback
    Callback handler = new ClallbackHandler();

    /* register this class as the handler for the event. In other words
    * call function 'fn' when some event we're interested in happens
    */
    event.registerCallback ( handler );
  }
}

/* some class that needs to call our callback */
public class EventHandler {
  public void registerCallback( Callback callbackObj ) {
    this.callback = callbackObj;
  }

  ...

  public void bar() {
    // this will call the function we defined in our CallbackHandler class
    this.callback.fn();
  }
  private Callback callback = null;
}



The able code contains three classes. The first class is the CallbackHandler which will contain the code for the actual implementation of the callback. Note that it extends from the 'Callback' class.

The second class is where you actually want to the callback to be implemented. i.e. this is where the object of the CallbackHandler will be created.

Finally the third class is where the Callback will be called from. Note here that it doesn't know anything about 'CallbackHandler' except that its derived from the 'Callback' class. This makes it possible to have multiple "CallbackHandler's".

Note that the principal remainds the same and this can be done in any language. However C++ and C# provide a way to pass around the function pointer itself without the need to wrap it into a class.

No comments: