tags:

views:

88

answers:

4

Hello,

I came across this question about callbacks in Java. Hers is the running code and original answer here.

  1. But I didn't understand how is it useful for callback?
  2. Can you explain the concept of callback to a Java programmer?

Code:

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));

    }
}
+2  A: 

I wrote a small blog post on this sometime back : http://madhurtanwani.blogspot.com/2010/09/callbacks-in-java.html. Hope it helps!

Before I try explaining the above code post, I must say, its not the most intuitive or good use of call backs. The example I've used in my post is of Collections.sort() which clearly brings out the callback part.

Neverthelss, for the code posted above, think of like this :

  1. The main() function actually is a number (read Data) stream parsing algorithm, which will parse a pair of numbers (data sets) and then operate on them.
  2. Now, considering separation of concerns, the main() function should neither know or understand what operations can be performed on the datasets. In fact it should not even care of the data types of the data sets.
  3. However, since these data sets are specific to your domain, the main function should ideally delegate the processing of the data to your domain specific classes.
  4. For it to do so, it must enforce a contract with the domain specific caller (the caller for main) and say - look, I'll call the doJob method on a Visitor interface implementations, whenever I receive a pair of data sets. What the caller must do is implement the Visitor interface and implement the domain specific logic to process the datasets.

The part of delegating processing from the caller, back to the callee is called a callback implemented using interface (contract specification) in Java.

madhurtanwani
interesting read, but I am also trying to understand the code posted.
zengr
A: 

You're talking about an entity I never called callbacks myself. The entities your are talking about are called function pointers (as mentioned by madhuranwani) / delegates / anonymous functions / actions.

These ones are usually used for customization of generic algorithm implementations (such as Collections.sort, as you mentioned).

    public class Actions {
    public static void main(String[] args) {
        printingAlgorithm(new Action() {

            public void perform() {
                System.out.println("CustomAction.perform");
            }
        });
    }

    private static void printingAlgorithm(Action customization) {
        System.out.println("------");
        customization.perform();
        System.out.println("++++++");
    }
}

interface Action {
    void perform();
}

Entity which are usually called callbacks in my area act more like listeners. Here is an example:

public class Callbacks {

    public static void main(String[] args) {
        printingAlgorithm(new PrintingCallback() {
            public void printBody() {
                System.out.println("custom body");
            }

            public void printHeader() {
                System.out.println("---------");
            }

            public void printFooter() {
                System.out.println("+++++++++");
            }
        });
    }

    private static void printingAlgorithm(PrintingCallback callback) {
        callback.printHeader();
        callback.printBody();
        callback.printFooter();
    }
}

interface PrintingCallback {
    void printHeader();

    void printBody();

    void printFooter();
}
Alex Nikolaenkov
A: 

They are called "Anonymous Inner Classes". They are basically an implementation of an interface/abstract class without having to write a fully blown class.

The compiler will actually create a class for each one of these, so if you compile the above code, you'll see something like:

Main.class
Main$Visitor.class
Main$1.class  <-- This is probably the "adder" implementation
Main$2.class  <-- This is probably the "multiplier" implementation

The beauty of these classes is that they can read stuff from your method/class without you having to pass those parameters. For instance:

...
final int extraMultiplyer = 10;

Visitor multiplier = new Visitor(){
    public int DoJob(int a, int b) {
        //Note that extraMultiplyer is defined in the main() method
        //and is final.
        return a*b*extraMultiplyer;
    }
};
...

They are particularly useful for event handling (think Swing), where you usually need to implement the ActionListener interface where you need to have a actionPerormed() method. If you have a UI class with many different controls, whenever you register the listeners, you might want to register these annonymous classes to: a) make the code (arguably) more readable and b) to make it easier to know what each component does, instead of having a giant "if-else if-else" style actionPerfomed implementation

for instance:

//abbreviated code
button1.addActionListener(new ActionListener(){
    //you do what you need here for the action of pressing this button
});
button2.addActionListener(new ActionListener() {
   //you do what you need here for the action of pressing this button
});
iggymoran
Based on your comment about what it's actually doing is: Creates classes that implement that interface and executes them. Similar (but not exactly the same, see post) as having a Visitor interface and 2 "named", "concrete" implementations of the interface, lets call them "MultiplierVisitor implements Visitor" and "AdderVisitor implements Visistor"
iggymoran
A: 

I don't want to start a flame war here... But the concept of callbacks is a lot easier to understand in languages like C/C++, JavaScript, Python, probably Ruby and many others. In such languages, a callback is just a function pointer. You pass your function as this function pointer, and the other code will call back your function using that pointer. As simple as that. (look at this C example from Wikipedia)

But Java does not have function pointers, and thus the Java programmer is required to use Anonymous Inner Classes, Interfaces and things like that in order to encapsulate a function inside a class, and pass an instance of that class as the callback.

I think I managed to answer your second question ("Can you explain the concept of callback to a Java programmer?"), but please see the other answers about how to implement that in Java.

Denilson Sá