Konner Rasmussen
Konner Rasmussen

Reputation: 179

Understanding callbacks in Java

I have been trying to wrap my head around callbacks and have been struggling to grasp the concept. The following code is an example that I found here

starting from first to last I understand the flow to be such:

I do not understand this code. How does doWork get called? How does this signify an event? Why would one not simply call interestingevent from the constructor of callme .... For that matter why not just call dowork in place of whatever would change the value of somethinghappened?

Try as I might I cannot seem to grasp the idea. I understand that callbacks are used primarily to signify an event has occurred such as a mouse or button click but how does it make the connection between the event occurring and the methods being called? Should there not be a loop that checks for changes, and thus triggers the event?

Can someone please provide a (not over-simplified) explanation of callbacks in java and help clarify how something like this could be useful?

public interface InterestingEvent
{
    public void interestingEvent ();
}

public class EventNotifier
{
    private InterestingEvent ie;
    private boolean somethingHappened; 
    public EventNotifier (InterestingEvent event)
    {
        ie = event; 
        somethingHappened = false;
    } 

    public void doWork ()
    {
        if (somethingHappened)
        {
            ie.interestingEvent ();
        }
    } 
}

public class CallMe implements InterestingEvent
{
    private EventNotifier en; 
    public CallMe ()
    {
        en = new EventNotifier (this);
    } 

    public void interestingEvent ()
    {
        // Wow!  Something really interesting must have occurred!
        // Do something...
    } 
}

EDIT: please see the comments in the approved answer... ---this--- link was very helpful for me =)

Upvotes: 0

Views: 573

Answers (2)

Steve P.
Steve P.

Reputation: 14699

There is no main method or static blocks. Nothing is actually run from the code you posted; hence, doWork() is never called. I read the article and looked at the code, and it appears to be incomplete, or perhaps some code is left out because the author felt that it didn't need to be explained.

Here's the gist:

We have an interface InterestingEvent, a class EventNotifier, and another class CallMe, which implements InterestingEvent.

EventNotifier takes an InterestingEvent in its constructor, and sets somethingHappened to false.

The constructor for CallMe initializes its EventNotifier instance member by passing the EventNotifier constructor a reference to the CallMe object, itself.

The following is not in the code, but if we detect that some particular action takes place, we set somethingHappened = true. So after that, if doWork() is called for an EventNotifier, interestingEvent() will be called on that EventNotifier's InterestingEvent ie. We can do this, since CallMe implements InterestingEvent.

NB: This article was from 1996 and much has changed since then. You mentioned how to detect mouse click events, but this is different. The point of the article, I assume, was to show how you can use objects in conjunction with interfaces and booleans to see if something occurred.

To actually detect a mouse click, take a look at this tutorial. Here's another tutorial on Writing Event Listeners. Finally, since you asked about threading in a comment, here's a great book: Java Concurrency in Practice.

Upvotes: 2

wjr
wjr

Reputation: 334

The way that I typically use callbacks is with PropertyChangeListeners/PropertyChangeSupport classes. There is probably of lot of different explanations about those classes that you might find helpful.

Anyway, to the point of your question.

First, you need to understand that the two classes you have are normally running on different threads. What the callback does is allow you to get an asynchronous notification that something has happened on the other thread. This allows the notified thread to do its part when it regains control. For example, you have a serial line that is receiving data. The InterestingEvent would be something like 10 characters have arrived on this line. Now, instead of having just one EventNotifier, you'd have one for each serial line coming in. The CallMe instance would be running doing something, periodically checking to see if interestingEvent had been called. interestingEvent would set some sort of flag so that CallMe would know that it had new data to process. When CallMe sees that, it takes care of whatever the interestingEvent was and then goes back to its normal activity.

The whole point of the interface is to have a well-defined way to access an instance of CallMe. If you develop this more, you are probably going to want to manage the other instances that are accessing your instance of CallMe. That's where reading up on the PropertyChange stuff that I mentioned earlier would be really helpful.

Upvotes: 2

Related Questions