方法上的泛型与类泛型参数无关
您需要在方法上重复它们才能使其正确,例如
Callback<Boolean> callback = new Callback<Boolean>() {
@Override
public <X,Y> Boolean execute(Operation<X, Y> operation) {
}
};
executor.execute(callback);
换句话说,接口需要一个处理任何操作参数的执行方法。
如果你想要一个只适用于特定参数的回调,你需要让它们成为类签名的一部分,例如
public interface Callback<T,K,V> {
T execute(Operation<K, V> operation) throws SomeException;
}
然后让你做
Callback<Boolean,String,String> callback = new Callback<Boolean,String,String>() {
@Override
public Boolean execute(Operation<String, String> operation) {
}
};
executor.execute(callback);
我看不到获得你想要的东西的途径...除非您开始使用或表单,否则可能会对您限制太多。<? super K,? super V>
<? extends K,? extends V>
这是您的界面擦除的内容
public interface Callback<T> {
T execute(Operation<Object, Object> operation) throws SomeException;
}
然后,当您实例化时,我们得到T == Boolean
public interface Callback {
Boolean execute(Operation<Object, Object> operation) throws SomeException;
}
不能由
Boolean execute(Operation<String, String> operation) throws SomeException;
方法,因为 in 参数较窄。您可以加宽参数和缩小参数范围,但不能走另一条路。
这就解释了为什么您可以将返回类型(out 参数)从 更改为,因为任何期望的人都对 .Object
Boolean
Object
Boolean
相反,我们不能扩大返回类型,因为这会给调用方法并对结果采取行动的任何人提供。ClassCastException
方法参数(在参数中)只能加宽。现在,方法参数有点复杂,因为Java将不同的类型视为不同的方法,因此您可以合法地拥有
public interface Callback<T> {
T execute(Object key, Object value);
}
Callback<Boolean> cb = new Callback<Boolean> {
@Override
public Boolean execute(Object k, Object v) { ... }
// not an @Override
public Boolean execute(String k, String v) { ... }
}
因为第二种方法具有不同的签名。但是,您的类将被擦除为原始类型,而不管它是 orOperation<X,Y>
Operation<String,String>
Operation<X,Y>
有一件事你可以做...但它变得凌乱!
public interface StringOperation extends Operation<String,String> {}
然后你可以做
Callback<Boolean> cb = new Callback<Boolean> {
@Override
public <K,V> Boolean execute(Operation<K,V> o) { ... }
// not an @Override
public Boolean execute(StringOperation o) { ... }
}
但请记住,该方法将调用而不是execute(Callback<?>)
<K,V> Boolean execute(Operation<K,V> o)
Boolean execute(StringOperation o)