2012-10-10 126 views
9

考虑下面的接口,java的实现通用接口,一个匿名类

public interface Callback<T> { 
    <K, V> T execute(Operation<K, V> operation) throws SomeException; 
} 

我将如何实现新的匿名类,其中operation是类型的接口Operation<String,String>

例如,这不编译:

Callback<Boolean> callback = new Callback<Boolean>() { 
     @Override 
     public Boolean execute(Operation<String, String> operation) { 
       return true; 
     } 
}; 
executor.execute(callback); 
+1

什么编译错误,你得到什么?我可以看到你的函数没有return语句,这是一个编译错误。 –

+1

编译错误的原因是什么? “SomeException”在哪里? – mishadoff

+2

我建议你不要重复使用任何常见类或接口的名称,而要使用不同的名称。重复使用名字会导致您的困惑。 –

回答

7

的方法的泛型是无关的类泛型参数

你需要重复他们的方法,因为它是正确的,例如

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; 

方法被实现为在参数更窄。您可以扩大参数范围并缩小参数,但不能以其他方式进行。

这就解释了为什么您可以将返回类型(输出参数)从Object更改为Boolean,因为任何预计Object的人都会对Boolean感到满意。

相反,我们不能扩大返回类型,因为那样会给ClassCastException任何人调用方法并对结果采取行动。

方法参数(在参数中)只能加宽。由于Java将不同类型看作不同的方法,所以现在对于方法参数有点复杂,因此您可以合法地拥有不同的签名,因为第二种方法的签名不同。但是您的Operation<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)

5

因为类名中的类型参数和方法中的类型参数实际上是不同的你可以做下方。

@Override 
    public <K, V> Boolean execute(Operation<K, V> operation) 
      throws SomeException { 
     return false; 
    } 
+0

这是可行的,但是如果我明确希望操作在侧面执行方法中使用泛型类型呢? – user1735096

+0

您必须将'回调'更改为'回调' –

+0

谢谢。不幸的是,在这种情况下,这不是我控制的接口。 – user1735096