泛型的引入使得 Java 語(yǔ)言中的類(lèi)型系統(tǒng)更加復(fù)雜。以前,該語(yǔ)言具有兩種類(lèi)型 —— 引用類(lèi)型和基本類(lèi)型。對(duì)于引用類(lèi)型,類(lèi)型 和類(lèi) 的概念基本上可以互換,術(shù)語(yǔ)子類(lèi)型 和子類(lèi) 也可以互換。
隨著泛型的引入,類(lèi)型和類(lèi)之間的關(guān)系變得更加復(fù)雜。List<Integer>
和 List<Object>
是不同的類(lèi)型,但是卻是相同的類(lèi)。盡管 Integer
擴(kuò)展 Object
,但是 List<Integer>
不是 List<Object>
,并且不能賦給 List<Object>
或者強(qiáng)制轉(zhuǎn)換成 List<Object>
。
另一方面,現(xiàn)在有了一個(gè)新的古怪的類(lèi)型叫做 List<?>
,它是 List<Integer>
和 List<Object>
的父類(lèi)。并且有一個(gè)更加古怪的 List<? extends Number>
。類(lèi)型層次的結(jié)構(gòu)和形狀也變得復(fù)雜得多。類(lèi)型和類(lèi)不再幾乎是相同的東西了。
extends 的新含意
在 Java 語(yǔ)言引入泛型之前,extends
關(guān)鍵字總是意味著創(chuàng)建一個(gè)新的繼承自另一個(gè)類(lèi)或接口的類(lèi)或接口。
引入泛型之后,extends
關(guān)鍵字有了另一個(gè)含意。將 extends
用在類(lèi)型參數(shù)的定義中(Collection<T extends Number>
)或者通配符類(lèi)型參數(shù)中(Collection<? extends Number>
)。
當(dāng)使用 extends
來(lái)指示類(lèi)型參數(shù)限制時(shí),不需要子類(lèi)-父類(lèi)關(guān)系,只需要子類(lèi)型-父類(lèi)型關(guān)系。還要記住,有限制類(lèi)型不需要是該限制的嚴(yán)格子類(lèi)型;也可以是 該限制。換句話說(shuō),對(duì)于 Collection<? extends Number>
,您可以賦給它 Collection<Number>
(盡管 Number
不是 Number
的嚴(yán)格子類(lèi)型)和 Collection<Integer>
、Collection<Long>
、Collection<Float>
等等。
在任何這些含意中,extends
右邊的類(lèi)型都可以是參數(shù)化類(lèi)型(Set<V> extends Collection<V>
)。