我有一个这样的界面:
public interface BatchSynchronisedPool<R extends Runnable> {
void execute(R runnable, Object batchIdentifier);
public <T> Future<T> submit(Callable<T> callable, Object batchIdentifier);
}
我想推断 Callable 的上限,但仍希望能够保持 <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
争论。但是,现在您已经大致了解了我正在尝试做的事情,是否有可能的解决方案,或者我是否总是不得不提交可调用文件? (或者完全删除泛型并执行不安全的转换)
最佳答案
我不是 100% 确定,但不要认为您可以在这里做您想做的事情。自 C
不是通用的,你不能使用 C<T>
.下面有很多代码,但是 tl;dr 选择选项 3。最终真正改变的是多少BatchSynchronisedPool
您需要创建的对象,这并不是一个很大的开销...
1.保留<T>
方法上的通用类型参数,提交 Callable<T>
并在实现此接口(interface)的类中执行类型的运行时检查,就像您的原始解决方案一样。
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
并在实现此接口(interface)的类中执行强制转换,就像您建议的那样。
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。创建一个新的 BatchSynchronisedPool
对于每种类型 T
您尝试通过指定 T
提交作为类的通用类型参数。然后每次你想调用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);
}
}
关于java - 组合类和方法参数化类型,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11645555/