Given the following interface,
public interface Callback<T> {
<K, V> T execute(Operation<K, V> operation) throws SomeException;
}
How would I implement the interface in a new anonymous class where operation
is of type Operation<String,String>
e.g, this doesn't compile:
Callback<Boolean> callback = new Callback<Boolean>() {
@Override
public Boolean execute(Operation<String, String> operation) {
return true;
}
};
executor.execute(callback);
the generics on the method are unrelated to the class generic parameters
you need to repeat them on the method for it to be correct, e.g.
In other words the interface requires an execute method that works on any Operation parameters.
If you want a callback that only works on specific parameters you need to make them part of the class signature, e.g.
that would then let you do
I cannot see a route to getting what you want... unless you start using the
<? super K,? super V>
or<? extends K,? extends V>
forms which may restrict you too much.Here is what your interface erases to
then when you instantiate with
T == Boolean
we getwhich cannot be implemented by a
method as the in parameters are narrower. You can widen in parameters and narrow out parameters but you cannot go the other way.
That explains why you can change the return type (out parameter) from
Object
toBoolean
as anyone expecting anObject
will be happy with aBoolean
.Conversely we cannot widen the return type as that would give a
ClassCastException
to anyone calling the method and acting on the result.The method arguments (in parameters) can only be widened. Now it is somewhat complex for method arguments as Java sees different types as different methods, so you can legally have
because the second method has a different signature. But your
Operation<X,Y>
class gets erased to just the raw type irrespective of whether it is anOperation<String,String>
orOperation<X,Y>
There is one thing you could do... but it gets messy!
then you can do
but keep in mind that the
execute(Callback<?>)
method will be calling<K,V> Boolean execute(Operation<K,V> o)
and notBoolean execute(StringOperation o)
Because the type parameter in your class name and the type parameter in the method are actually different You can do below.