2012-07-25 12 views
4

我有一個這樣的接口:結合類和方法的參數類型

public interface BatchSynchronisedPool<R extends Runnable> { 
    void execute(R runnable, Object batchIdentifier); 
    public <T> Future<T> submit(Callable<T> callable, Object batchIdentifier); 
} 

我想推斷的上限可贖回,但還是希望能夠保持<T>參數的方法:

public interface BatchSynchronisedPool<R extends Runnable, C extends Callable> { 
    void execute(R runnable, Object batchIdentifier); 
    public <T> Future<T> submit(C<T> callable, Object batchIdentifier); 
} 

很明顯,這是行不通的,因爲我指定的C的類型可能只取參數的一個特定範圍T。然而,現在你只有我想要做的一般事情,有沒有可能的解決方案,還是我堅持總是提交一個可調用的? (或者完全刪除泛型並執行不安全的演員表)

回答

4

我不是100%確定的,但不要以爲你可以做你想要做的事情。由於C不是通用的,因此不能使用C<T>。下面有很多代碼,但tl; dr 採取選項3。所有這一切真正改變到底是你有多少BatchSynchronisedPool對象需要創建,這是不是一個真正的相當大的開銷......


保持<T>泛型類型參數的方法, 提交一個Callable<T>,並在實現此接口的類中執行類型的運行時檢查,如原始解決方案。

public interface BatchSynchronisedPool<R extends Runnable> { 
    void execute(R runnable, Object batchIdentifier); 
    public <T> Future<T> submit(Callable<T> callable, Object batchIdentifier); 
} 

public class MyBSP<R, C> implements BatchSynchronisedPool<R, C> { 
    void execute(R runnable, Object batchIdentifier) { ... } 
    public <T> Future<T> submit(Callable<T> callable, Object batchIdentifier) { 
     // Check types. 
     if (!(callable instanceof MyDesiredCallableClass)) { 
      throw new IllegalArgumentException("Types don't match."); 
     } 

     // Do work. 
     T result = callable.call(); 

     ... 
    } 
} 

public class MyUsageClass { 
    public static void main(String[] args) { 
     // Submit string. 
     MyBSP<Runnable> bsp = new MyBSP<Runnable>(); 
     bsp.submit(new StringCallable(), someObject1); 

     // Submit integer. 
     bsp.submit(new IntegerCallable(), someObject2); 
    } 
} 

2.保持在方法<T>泛型類型參數,提交C和執行鑄造,就像你所說,在實現該接口的類。

public interface BatchSynchronisedPool<R extends Runnable, C extends Callable> { 
    void execute(R runnable, Object batchIdentifier); 
    public <T> Future<T> submit(Class<T> cls, C callable, Object batchIdentifier); 
} 

public class MyBSP<R, C> implements BatchSynchronisedPool<R, C> { 
    void execute(R runnable, Object batchIdentifier) { ... } 
    public <T> Future<T> submit(Class<T> cls, C callable, Object batchIdentifier) { 
     // Do work... with a cast. 
     T result = cls.cast(callable.call()); 

     ... 
    } 
} 

public class MyUsageClass { 
    public static void main(String[] args) { 
     // Submit string. 
     MyBSP<Runnable, Callable> bsp = new MyBSP<Runnable, Callable>(); 
     bsp.submit(new StringCallable(), someObject1); 

     // Submit integer. 
     bsp.submit(new IntegerCallable(), someObject2); 
    } 
} 

3.爲每種類型的T,你試圖通過指定T作爲該類的泛型類型參數提交新BatchSynchronisedPool。然後,每次您想以不同類型撥打submit時,都需要生成BatchSynchronisedPool的新實例。

public interface BatchSynchronisedPool<T, R extends Runnable, C extends Callable<T>> { 
    void execute(R runnable, Object batchIdentifier); 
    public Future<T> submit(C callable, Object batchIdentifier); 
} 

public class MyBSP<T, R, C> implements BatchSynchronisedPool<T, R, C> { 
    void execute(R runnable, Object batchIdentifier) { ... } 
    public Future<T> submit(C callable, Object batchIdentifier) { 
     // Do work. Types are okay; no checking or casting needed! 
     T result = callable.call(); 

     ... 
    } 
} 

public class MyUsageClass { 
    public static void main(String[] args) { 
     // Submit string. 
     MyBSP<String, Runnable, Callable<String>> stringBsp = new MyBSP<String, Runnable, Callable<String>>(); 
     stringBsp.submit(new StringCallable(), someObject1); 

     // Submit integer. 
     MyBSP<Integer, Runnable, Callable<Integer>> integerBsp = new MyBSP<Integer, Runnable, Callable<Integer>>(); 
     integerBsp.submit(new IntegerCallable(), someObject2); 
    } 
} 
+2

如果你在運行時類中(2),你可以做一個檢查轉換,避免在'T結果=(T)callable.call()的警告與''T導致= CLS。 cast(callable.call())' – artbristol 2012-07-25 13:05:42

+0

是的。變了!謝謝。 – 2012-07-25 13:09:53

+1

好的答案,但我看到了一些錯誤:在** 2。**和** 3。**'MyBSP'沒有正確地實現接口,因爲'submit'方法具有不同的簽名。在** 2中,接口中的'submit'方法應該有'Class '參數。在** 3。**中,由於類也是用'T'進行參數化的,所以我會從類方法中刪除'Class '參數,並將其移至構造函數中。我的2美分。 – 2012-07-25 14:30:02