4

I really want to create a subclass of FutureTask that has a default no-arg constructor. In particular, I want my subclass to implement the Callable interface and use itself as the callable. This way, users of MyFutureTask can just subclass MyFutureTask instead of having to implement their own callable and pass it to an instance of FutureTask.

Here's the general idea:

public abstract class MyFutureTask<Result> extends FutureTask<Result> implements Callable<Result> {

    public MyFutureTask() {
        super( /*XXX*/ );        
    }

    public abstract Result call() throws Exception;

}

The problem is, what can I put in the XXX? FutureTask requires a Callable, but I can't pass this because java doesn't allow references to this from within a call to super. I can't instantiate a nested class since that's also disallowed.

Is there a clever (or non-clever) way I can do this?

emmby
  • 99,783
  • 65
  • 191
  • 249
  • I'm still not clear why you want to do this? You generally don't create FutureTasks yourself, you realy on the ScheduledExecutorService to turn your Callable into a FutureTask. – skaffman Sep 24 '09 at 07:38
  • If you want to implement cancellable computations you will have to do it yourself. – MrWhite Sep 24 '09 at 10:04
  • You ask how you can realize this design, but I fear that even if you're successful, your clients will be mystified. Is the outcome of them calling MyFutureTask#call() at all related to to the relationship between RunnableFuture#run() and Future#get()? Is your call() function mean to be the equivalent of run() followed by get()? – seh Nov 22 '09 at 00:46

1 Answers1

2

You could do this using composition and the creation of an abstract class. now you clients are decoupled from the callable interface.

import java.util.concurrent.Callable;
import java.util.concurrent.FutureTask;

public abstract class MyFutureClass<V> implements Callable<V> {

private final FutureTask<V> futureTask;

public MyFutureClass() {
    futureTask = new FutureTask<V>(this);
}

@Override
public V call() throws Exception {
    return myCall();
}

protected abstract V myCall();

public FutureTask<V> getFutureTask() {
    return futureTask;
}
}
Robert Munteanu
  • 67,031
  • 36
  • 206
  • 278
MrWhite
  • 191
  • 1
  • 8
  • Great, thanks guys. Yeah, that would work, although it has the disadvantage of not extending from FutureTask, so I can't pass it in anywhere that expects a FutureTask. So far though it's the best solution I've seen, unfortunately. – emmby Sep 25 '09 at 19:41