6

I'm pretty new to Java but I need to write something like this C# code (this is hand-typed prototype just to illustrate what I need)

private void ParentFunc()
{
    var worker = new WorkerClass()

    worker.DoWork(e => console.Write("Progress" + e));


}

public class WorkerClass()
{
    public method DoWork(Action<int> callback)
    {
        for (int i=1; i<1000; i++) callback.Invoke(i);  
    }
}

Little explanation. I'm using AsyncTask in android and calling outside processor classed but would like them to signal back so I can publishProgress. I prefer not to put interface over my AsyncTask

katit
  • 17,375
  • 35
  • 128
  • 256
  • 2
    possible duplicate of [Callback functions in Java](http://stackoverflow.com/questions/443708/callback-functions-in-java) – assylias Jun 06 '12 at 17:21

4 Answers4

6

Since closures are not supported yet you have to use interface and anonymous inner class.

private void ParentFunc {
    WorkerClass worker = new WorkerClass();

    worker.doWork(new Callback<Integer>() {
        public void invoke(Integer arg) {
            System.out.println("Progress" + arg);
        }
    });
}

public class WorkerClass {
    public doWork(Callback<Integer> callback) {
        for (int i=1; i<1000; i++) callback.invoke(i);  
    }
}

public interface Callback<T> {
    public void invoke(T arg);
}
AlexR
  • 114,158
  • 16
  • 130
  • 208
5

In java, you use anonymous classes implementing interfaces. This is somewhat more verbose, but it works just fine:

interface MyAction {
    void doit(String str);
}

class WorkerClass {
    void doWork(MyAction action);
}

void main(String args[]) {
    WorkerClass worker = new WorkerClass();
    worker.doWork(new MyAction {
        public void doit(String e) {
            System.out.println("Progress" + e)
        }
    });
}
Sergey Kalinichenko
  • 714,442
  • 84
  • 1,110
  • 1,523
4

With the aid of a support class:

interface CallBack<P>
{
  public void callback(P p);
}

class MyCallBack implements CallBack<String> {
  public void callBack(String p) {
    System.out.println(p);
  }
}

class WorkerClass {
  public void doWork(CallBack<String> callback)
  {
    // do work
    callback.callBack("Done!");
  }
}

WorkerClass wc = new WorkerClass();
wc.doWork(new MyCallBack());

I'm not going to suggest you to use anonymous classes because I find them quite verbose until a slicker syntax won't be available but it's just a matter of personal taste, I end up losing my self between braces when I use them..

Jack
  • 131,802
  • 30
  • 241
  • 343
0

It is possible with java 8. See my answer to the duplicate question:

https://stackoverflow.com/a/26776520/1206998

Use a function as argument:

import java.util.function.Function;

public String applyFunction(Function<String,String> function){
        return function.apply("what ever");
}

Call

// with someObject.someMethod(String) => String
xxx.applyFunction(someObject::someMethod);
Community
  • 1
  • 1
Juh_
  • 14,628
  • 8
  • 59
  • 92