Question

I have defined following classes:

class Operation<S>
class GetReservationOperation extends Operation<Reservation>

Now I would like to have a class like this:

OperationExecutor<T extends Operation<S>> extends AsyncTask<T,Void,S>{
    @Override
    protected S doInBackground(T... params) {
       return null;
    }
}

But this won't compile:

OperationExecutor<GetReservationOperation> executor = new ....

Why doesn't Java allow this?

After some time I came up with the following solution:

OperationExecutor<T extends Operation<S>,S> extends AsyncTask<T,Void,S>{
    @Override
    protected S doInBackground(T... params) {
       return null;
    }
}

But this forces me to write the following:

OperationExecutor<GetReservationOperation,Reservation> executor = new .... 

Which looks odd. Is there any way to make it look nicer?

EDIT This worked

OperationExecutor<S> extends AsyncTask<Operation<S>,Void,S>{
    @Override
    protected S doInBackground(Operation<S>... params) {
       return null;
    }
}

OperationExecutor<Reservation> executor = new ....
executor.execute(getReservationOperation);
Was it helpful?

Solution

Now I would like to have a class like this

OperationExecutor<T extends Operation<S>> extends AsyncTask<T,Void,S>{
    @Override
    protected S doInBackground(T... params) {
       return null;
    }
}

The reason this doesn't work is because S hasn't been declared anywhere, only referenced as a type argument in T's bound. Java needs S to be declared for other references to it to make sense, for example protected S doInBackground and AsyncTask<T,Void,S>.

One thing you might consider is whether OperationExecutor needs to be generic to a specific type of Operation<S>. You could do this instead for example:

OperationExecutor<S> extends AsyncTask<Operation<S>, Void, S> {
    @Override
    protected S doInBackground(Operation<S>... params) {
       return null;
    }
}
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top