[英]How can I make my generics code compatible with this method signature?
I have a variation of the following code: 我有以下代码的变体:
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);
}
}
And as you can see, my queue is not compatible with the ThreadPoolExecutor
constructor. 正如您所看到的,我的队列与
ThreadPoolExecutor
构造函数不兼容。 Is there any way to work around this than cast my queue to (BlockingQueue<Runnable>)
? 有没有办法解决这个问题,而不是将我的队列强制转换为
(BlockingQueue<Runnable>)
? I obviously can't patch Java Standard Library. 我显然无法修补Java标准库。
No, and you shouldn't . 不, 你不应该 。
Your BlockingQueue<MyRunnable>
should, of course, only contain MyRunnable
s. 当然,你的
BlockingQueue<MyRunnable>
应该只包含MyRunnable
。 But the ThreadPoolExecutor
can submit arbitrary Runnable
tasks to the queue you give it: see execute(Runnable command)
. 但是
ThreadPoolExecutor
可以将任意Runnable
任务提交给你给它的队列:请参阅execute(Runnable command)
。
If that happens, you could have a non- MyRunnable
instance in your queue. 如果发生这种情况,您的队列中可能会有一个非
MyRunnable
实例。 You then try to poll from your reference of that queue (typed as a BlockingQueue<MyRunnable>
), and get a ClassCastException
. 然后尝试从该队列的引用中进行轮询(键入为
BlockingQueue<MyRunnable>
),并获取ClassCastException
。
Simple example: 简单的例子:
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
The above code will throw an exception if the queue.poll()
happens before the thread pool has had a chance to dequeue the WhateverRunnable
instance. 如果
queue.poll()
在线程池有机会使WhateverRunnable
实例出列之前发生,则上面的代码将抛出异常。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.