2012-10-10 48 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