简体   繁体   中英

Callable with different return types

I would like to execute different methods in a separate thread depending on the parameters that are given to the constructor. However, the Callable interface only allows one kind of return parameter.

It should work like this:

Future<String> result =
       executor.submit(ClassThatImplementsCallable(RETURN_STRING));
Future<Integer> result =
       executor.submit(ClassThatImplementsCallable(RETURN_INT));

ClassThatImplementsCallable(RETURN_NOTHING);

To return either null (respectively the reference to Void) or any other type like String or Integer I have to use T without any bounds like this:

public static class CallableTest<T> implements Callable<T>{
    T value;
    CallableTest(T value) {
       this.value = value;
    }
    public T call(){    
       return value;   
    }    
}

However, this is not what I want to achieve, but it also doesn't make sense to extend Void and implement some other interface.

I would like to execute different methods in a separate thread depending on the parameters that are given to the constructor.

So when you submit a Callable to an ExecutorService , you get a future with the same type:

Future<String> stringResult = executor.submit(new MyCallable<String>());
Future<Integer> stringResult = executor.submit(new MyCallable<Integer>());

What you can't do is have a single Future result that returns one of two different types, either String or Integer , based on arguments when the ExecutorService was constructed. I think that is what you are asking.

One alternative would be for you to create a little wrapper class:

public class StringOrInteger {
    final String s;
    final Integer i;
    public StringOrInteger(String s) {
        this.s = s;
        this.i = null;
    }
    public StringOrInteger(Integer i) {
        this.s = null;
        this.i = i;
    }
    public boolean isString() {
        return this.s != null;
    }
}

Then your executor will submit Callable<StringOrInteger> and the instances of StringOrInteger returned by the Future<StringOrInteger> will either the s or i field will be set.

An extremely ugly alternative would be to return Object and use instanceof to figure out what type it is. But I won't even show the code for that implementation because it would give me hives.

you could use the Command pattern together with Visitor pattern.

Define a command class and wrap your processing logic together with parameters and return types in it. then pass this command object as parameter and also use it as result type.

Later in your code you can use visitor pattern in order to deal with the two concrete commands.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM