2014-09-16 12 views
0

Я использую код ThreadPoolExecutor в некотором коде, и я снабжаю его BlockingQueue<Runnable>. Я получаю ошибку компилятора: can't resolve constructor. Поэтому я попробовал лить queue явно BlockingQueue<Runnable>. Тем не менее, я получаю ошибку компилятора по конструктору ThreadPoolExecutor «s:Java BlockingQueue <Runnable> Неконвертируемые типы

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

Это происходит, даже если PriorityBlockingQueue орудия BlockingQueue и MyRunnable орудия Runnable. Я использую Java 7 на Android.

Код:

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 a BlockingQueue<Runnable>, но тогда мне нужно бросить кучу мест по всему моему коду, который я бы предпочел не делать.

Есть ли что-то, что мне не хватает, или это непроверенное предупреждение - мой лучший выстрел.

+1

Обратите внимание на разницу между 'BlockingQueue ' и 'BlockingQueue '. Очередь, которую вы поставляете, совместима только с одним из них. – Ordous

ответ

1

параметризованные типов в Java являются инвариантной, что означает, что X<SubT> не является ни подтипом, ни супертип X<T>. Вы ожидаете, что они будут covariant, так что X<SubT> будет подтип X<T>.

Если это было верно для системы типа generic типа Java, это было бы фактически очень непрактичным и приводило бы к типу-небезопасности. Например, ваш ThreadPoolExecutor хочет BlockingQueue<Runnable>, так как он может разместить любой видRunnable, а не только ваш MyRunnable. Нет такой вещи, как ThreadPoolExecutor<MyRunnable>.

Итак, если ваше ожидание было истинным, вы должны были пройти в очередь, которая работает только с MyRunnable s, но было бы предложено поставить в очередь, скажем TheirRunnable. Это должно было бы сломаться либо когда элемент находится в очереди, либо когда он отменен как MyRunnable.

+1

Да. Нет. Это ничего не сломает. Вы забыли про стирание :) Это сломается, если OP попытается использовать очередь для своих целей *, одновременно используя ее как очередь исполнителя *. Позаботьтесь о том, почему это разрешает типу, а затем работать нормально для бонусных очков? – Ordous

+1

Я не забыл про стирание. Либо тот факт, что он является «Очередь », никогда не будет реализовываться (только для удаления «Runnable's»), иначе он сломается с «ClassCastException». Поэтому он не будет ломаться только в том случае, если использование очереди 'не является проблемой. –

+0

Итак, это непроверенный актер, единственный способ, по которому я могу пойти здесь (не считая 'queue'' 'BlockingQueue '? – Eliezer

Смежные вопросы