我在某些代码中使用了ThreadPoolExecutor
,并为其提供了BlockingQueue<Runnable>
。我收到编译错误can't resolve constructor
。所以我尝试将queue
明确地投射到BlockingQueue<Runnable>
。但是,ThreadPoolExecutor
的构造函数导致编译错误:
Inconvertible types, cannot cast PriorityBlockingQueue<MyRunnable> to BlockingQueue<Runnable>
即使PriorityBlockingQueue
实施BlockingQueue
而MyRunnable
实施Runnable
,也会发生这种情况。我在Android上使用Java 7。
代码:
public class Test {
PriorityBlockingQueue<MyRunnable> queue = new PriorityBlockingQueue<>(...);
//compiler error without cast
ThreadPoolExecutor executor = new ThreadPoolExecutor(..., queue, ...);
//compiler error with cast
ThreadPoolExecutor executor = new ThreadPoolExecutor(..., (BlockingQueue<Runnable> queue, ...);
public static class MyRunnable implements Runnable {...}
临时解决方案:
为了让它进行编译,我已将演员阵容更改为(BlockingQueue)
,但我收到了未经检查的案例警告(我已将其删除)。我知道我可以让queue
成为BlockingQueue<Runnable>
但是我必须在我的代码中插入一堆我不想做的地方。
是否有我失踪的东西,或者是未经检查的警告我的最佳照片。
答案 0 :(得分:1)
Java中的参数化类型是不变,这意味着X<SubT>
既不是子类型也不是X<T>
的超类型。您希望它们是协变,因此X<SubT>
将是X<T>
的子类型。
如果Java的通用类型系统也是如此,它实际上是非常不切实际的并且导致类型不安全。例如,您的ThreadPoolExecutor
想要一个BlockingQueue<Runnable>
,因为它可能会将任何类型的 Runnable
放入其中,而不仅仅是MyRunnable
。没有ThreadPoolExecutor<MyRunnable>
之类的东西。
所以,如果你的期望是真的,你就会传入一个仅与MyRunnable
一起使用的队列,但会被要求入队,比如TheirRunnable
。当项目入队时,或者当它作为MyRunnable
出列时,这将不得不中断。