Java BlockingQueue <runnable>不可转换类型</runnable>

时间:2014-09-16 10:05:22

标签: java android casting polymorphism

我在某些代码中使用了ThreadPoolExecutor,并为其提供了BlockingQueue<Runnable>。我收到编译错误can't resolve constructor。所以我尝试将queue明确地投射到BlockingQueue<Runnable>。但是,ThreadPoolExecutor的构造函数导致编译错误:

Inconvertible types, cannot cast PriorityBlockingQueue<MyRunnable> to BlockingQueue<Runnable>

即使PriorityBlockingQueue实施BlockingQueueMyRunnable实施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>但是我必须在我的代码中插入一堆我不想做的地方。

是否有我失踪的东西,或者是未经检查的警告我的最佳照片。

1 个答案:

答案 0 :(得分:1)

Java中的参数化类型是不变,这意味着X<SubT>既不是子类型也不是X<T>的超类型。您希望它们是协变,因此X<SubT>将是X<T>的子类型。

如果Java的通用类型系统也是如此,它实际上是非常不切实际的并且导致类型不安全。例如,您的ThreadPoolExecutor想要一个BlockingQueue<Runnable>,因为它可能会将任何类型的 Runnable放入其中,而不仅仅是MyRunnable。没有ThreadPoolExecutor<MyRunnable>之类的东西。

所以,如果你的期望是真的,你就会传入一个仅与MyRunnable一起使用的队列,但会被要求入队,比如TheirRunnable。当项目入队时,或者当它作为MyRunnable出列时,这将不得不中断。