我不是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),你可以做一個檢查轉換,避免在'T結果=(T)callable.call()的警告與''T導致= CLS。 cast(callable.call())' – artbristol 2012-07-25 13:05:42
是的。變了!謝謝。 – 2012-07-25 13:09:53
好的答案,但我看到了一些錯誤:在** 2。**和** 3。**'MyBSP'沒有正確地實現接口,因爲'submit'方法具有不同的簽名。在** 2中,接口中的'submit'方法應該有'Class'參數。在** 3。**中,由於類也是用'T'進行參數化的,所以我會從類方法中刪除'Class '參數,並將其移至構造函數中。我的2美分。 –
2012-07-25 14:30:02