你得到一個錯誤,因爲Pair<String, Future<String>>
不是Pair<String, Future<?>>
。泛型類型不是協變的。
但是,您可以爲List<Pair<String, ? extends Future<?>>>
型futureTasks
。然後你就可以添加一個Pair<String, Future<String>>
它。
編輯:
爲了解釋這更好的,想嘗試分配對象的變量,而不是將其添加到列表中。如果我們有一個List<T>
,我們如果是一個T
只添加一個對象。因此,這是真的了同樣的情況:
Pair<String, Future<String>> pairOfStringAndFutureOfString;
Pair<String, Future<?>> pairOfStringAndFutureOfSomething;
// incompatible types
pairOfStringAndFutureOfSomething = pairOfStringAndFutureOfString;
再次,這是不允許的,因爲泛型不是協變。爲什麼?試想,如果他們是會發生什麼:
Future<Integer> futureOfInt;
Future<?> futureOfSomething;
futureOfSomething = futureOfInt; // a future of int is a future of something
Pair<String, Future<String>> pairOfStringAndFutureOfString;
Pair<String, Future<?>> pairOfStringAndFutureOfSomething;
// pretend this is legal
pairOfStringAndFutureOfSomething = pairOfStringAndFutureOfString;
// danger!
pairOfStringAndFutureOfSomething.setRight(futureOfSomething);
Future<String> futureOfString = pairOfStringAndFutureOfString.getRight();
//sometime later...
String string = futureOfString.get(); //ClassCastException
我們得到了futureOfString
指向的東西,實際上是一個Future<Integer>
。但是這甚至不會立即導致ClassCastException
,因爲由於類型擦除,JVM只看到Future
s。這種情況被稱爲「堆污染」 - 一個變量指向一個它不應該被允許的對象。實際運行時錯誤只發生在我們嘗試解包futureOfString
時發生。
所以這解釋了爲什麼泛型不是協變。讓我們看看解決方法:
Pair<String, ? extends Future<?>>
pairOfStringAndSomethingThatIsAFutureOfSomething;
該變量名稱是滿口的,但我希望它能夠準確描述這裏發生了什麼。之前,第二類型的論據是正是Future<?>
。現在,我們說這是「一些未知類型,它或擴展Future<?>
。例如,它可能是Future<?>
,也可能是Future<String>
,它甚至可以是MySpecialFuture<Integer>
。
我們主動放棄了一些資料關於這個變量,以放鬆身心什麼可以分配給它的類型現在,這是合法的:
pairOfStringAndSomethingThatIsAFutureOfSomething = pairOfStringAndFutureOfString;
編譯器通過阻止這種未知類型被防止早期的「堆污染」情景「消費「:
//compiler error - nothing can be legally passed into setRight
pairOfStringAndSomethingThatIsAFutureOfSomething.setRight(futureOfSomething);
要了解有關這些限制的更多信息,請參閱此帖:What is PECS (Producer Extends Consumer Super)?
爲什麼不能將它聲明爲'List >>'? –
2013-04-25 03:36:47
未來可能不會是字符串 – jamee 2013-04-25 03:38:29
然後聲明它爲'List >>'。至於你爲什麼不能用通配符'.add()':http://stackoverflow.com/q/3716920/和http://stackoverflow.com/q/69702/ –
2013-04-25 03:39:22