如何使我的泛型代码与此方法签名兼容?

Zty*_*tyx 5 java generics

我有以下代码的变体:

package com.test.package;

import java.util.concurrent.BlockingQueue;
import java.util.concurrent.PriorityBlockingQueue;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;

public class TestClass {

    public static class MyRunnable implements Runnable {

        @Override
        public void run() {
            System.out.println("Called");
        }

    }

    public void method() {
        PriorityBlockingQueue<MyRunnable> queue = new PriorityBlockingQueue<MyRunnable>();
        method2(queue);
    }

    public void method2(BlockingQueue<? extends Runnable> queue) {
        System.out.println(queue);

        // Getting error here because BlockingQueue<? extends Runnable> is not a
        // subtype of BlockingQueue<Runnable>.
        ThreadPoolExecutor threadPool = new ThreadPoolExecutor(200, 200, 0L,
            TimeUnit.MILLISECONDS, queue);
    }
}
Run Code Online (Sandbox Code Playgroud)

正如您所看到的,我的队列与ThreadPoolExecutor构造函数不兼容.有没有办法解决这个问题,而不是把我的队列投入(BlockingQueue<Runnable>)?我显然无法修补Java标准库.

ysh*_*vit 7

不,你不应该.

BlockingQueue<MyRunnable>当然,你应该只包含MyRunnables.但是ThreadPoolExecutor可以将任意Runnable任务提交给你给它的队列:看execute(Runnable command).

如果发生这种情况,您MyRunnable的队列中可能会有非实例.然后,您尝试从该队列的引用中进行轮询(键入为a BlockingQueue<MyRunnable>),然后获取ClassCastException.

简单的例子:

PriorityBlockingQueue<MyRunnable> queue = new PriorityBlockingQueue<>();
ThreadPoolExecutor threadPool = new ThreadPoolExecutor(200, 200, 0L,
        TimeUnit.MILLISECONDS, queue);
threadPool.execute(new WhateverRunnable());
MyRunnable myRunnable = queue.poll(); // this could throw ClassCastException
Run Code Online (Sandbox Code Playgroud)

如果在queue.poll()线程池有机会使WhateverRunnable实例出列之前发生,则上述代码将抛出异常.