java在匿名类中实现generics接口
鉴于以下界面,
public interface Callback { T execute(Operation operation) throws SomeException; }
如何在一个新的匿名类中实现接口,其中operation
类型为Operation
例如,这不编译:
Callback callback = new Callback() { @Override public Boolean execute(Operation operation) { return true; } }; executor.execute(callback);
方法上的generics与类generics参数无关
你需要在方法上重复它们才能使它正确,例如
Callback callback = new Callback () { @Override public Boolean execute(Operation operation) { } }; executor.execute(callback);
换句话说,接口需要一个适用于任何Operation参数的execute方法。
如果你想要一个仅适用于特定参数的回调,你需要让它们成为类签名的一部分,例如
public interface Callback { T execute(Operation operation) throws SomeException; }
然后会让你这样做
Callback callback = new Callback() { @Override public Boolean execute(Operation operation) { } }; executor.execute(callback);
我无法看到获得你想要的东西……除非你开始使用 super K,? super V>
super K,? super V>
super K,? super V>
或 extends K,? extends V>
extends K,? extends V>
extends K,? extends V>
forms可能会限制你太多。
这是您的界面擦除的内容
public interface Callback { T execute(Operation
然后当你用T == Boolean
实例化时,我们得到了
public interface Callback { Boolean execute(Operation
一个不能实现的
Boolean execute(Operation operation) throws SomeException;
in参数的方法较窄。 您可以扩大参数并缩小参数范围,但不能采用其他方式。
这就解释了为什么你可以将返回类型(out参数)从Object
更改为Boolean
因为任何人都期望Object
会对Boolean
感到满意。
相反,我们不能扩展返回类型,因为这会给任何调用方法并对结果起作用的人提供ClassCastException
。
方法参数(在参数中)只能加宽。 现在,对于方法参数来说有点复杂,因为Java将不同的类型视为不同的方法,因此您可以合法地拥有
public interface Callback { T execute(Object key, Object value); } Callback cb = new Callback { @Override public Boolean execute(Object k, Object v) { ... } // not an @Override public Boolean execute(String k, String v) { ... } }
因为第二种方法有不同的签名。 但是,您的Operation
类将被删除为原始类型,而不管它是Operation
还是Operation
你可以做一件事……但它变得凌乱!
public interface StringOperation extends Operation {}
那么你可以做到
Callback cb = new Callback { @Override public Boolean execute(Operation o) { ... } // not an @Override public Boolean execute(StringOperation o) { ... } }
但请记住, execute(Callback>)
方法将调用
而不是Boolean execute(StringOperation o)
因为类名中的type参数和方法中的type参数实际上是不同的,所以您可以在下面执行。
@Override public Boolean execute(Operation operation) throws SomeException { return false; }