版權(quán)說(shuō)明:本文檔由用戶(hù)提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請(qǐng)進(jìn)行舉報(bào)或認(rèn)領(lǐng)
文檔簡(jiǎn)介
1、java 通配符 2008-05-28 15:36通配符基本介紹Brian Goetz (brian.goetz@sun.com), 高級(jí)工程師, Sun Microsystems泛型是一種表示類(lèi)或方法行為對(duì)于未知類(lèi)型的類(lèi)型約束的方法,比如 “不管這 個(gè)方法的參數(shù) x 和 y 是哪種類(lèi)型,它們必須是相同的類(lèi)型”,“必須為這些方法提供同一類(lèi)型的參數(shù)” 或者 “foo() 的返回值和 bar() 的參數(shù)是同一類(lèi) 型的”。通配符 — 使用一個(gè)
2、奇怪的問(wèn)號(hào)表示類(lèi)型參數(shù) — 是一種表示未知類(lèi)型的類(lèi)型 約束的方法。通配符并不包含在最初的泛型設(shè)計(jì)中(起源于 Generic Java(GJ)項(xiàng)目),從形成 JSR 14 到發(fā)布其最終版本之間的五年多時(shí)間內(nèi)完成設(shè)計(jì)過(guò)程并被添加到了泛型中。通配符在類(lèi)型系統(tǒng)中具有重要的意義,它們?yōu)橐粋€(gè)泛型類(lèi)所指定的類(lèi)型集合提供了一個(gè)有用的類(lèi)型范圍。對(duì)泛型類(lèi) ArrayList 而言,對(duì)于任意(引用)類(lèi)型 T,ArrayList 類(lèi)型是 ArrayList
3、的超類(lèi)型(類(lèi)似原始類(lèi)型 ArrayList 和根類(lèi)型 Object,但是這些超類(lèi)型在執(zhí)行類(lèi)型推斷方面不是很有用)。 通配符類(lèi)型 List 與原始類(lèi)型 List 和具體類(lèi)型 List 都不相同。 如果說(shuō)變量 x 具有 List 類(lèi)型,這表示存在一些 T 類(lèi)型,其中 x 是 List類(lèi)型,x 具有相同的結(jié)構(gòu),盡管我們不知道其元素的具體類(lèi)型。這并不表示它可以具有任意內(nèi)容,而是指我們并不了解內(nèi)容的類(lèi)型限制是什么 — 但我們知道存在 某種限制。另
4、一方面,原始類(lèi)型 List 是異構(gòu)的,我們不能對(duì)其元素有任何類(lèi)型限制,具體類(lèi)型 List 表示我們明確地知道它能包含 任何對(duì)象(當(dāng)然,泛型的類(lèi)型系統(tǒng)沒(méi)有 “列表內(nèi)容” 的概念,但可以從 List之類(lèi)的集合類(lèi)型輕松地理解泛型)。通配符在類(lèi)型系統(tǒng)中的作用部分來(lái)自其不會(huì)發(fā)生協(xié)變(covariant)這一特性。 數(shù)組是協(xié)變的,因?yàn)?Integer 是 Number 的子類(lèi)型,數(shù)組類(lèi)型 Integer[] 是 Number[] 的子類(lèi)型,因此在任
5、何需要 Number[] 值的地方都可以提供一個(gè) Integer[] 值。另一方面,泛型不是協(xié)變的, List 不是 List 的子類(lèi)型,試圖在要求 List 的位置提供 List 是一個(gè)類(lèi)型錯(cuò)誤。這不算很?chē)?yán)重的問(wèn)題 — 也不是所有人都認(rèn)為 的錯(cuò)誤 — 但泛型和數(shù)組的不同行為的確引起了許多混亂。我已使用了一個(gè)通配符 — 接下來(lái)呢?清單 1 展示了一個(gè)簡(jiǎn)單的容器(container)類(lèi)型 Box,它支持 put 和 get 操作。 B
6、ox 由類(lèi)型參數(shù) T 參數(shù)化,該參數(shù)表示 Box 內(nèi)容的類(lèi)型, Box 只能包含 String 類(lèi)型的元素。public void rebox(Box box) {box.put(box.get()); }Rebox.java:8: put(capture#337 of ?) in Box cannot be appliedto (java.lang.Object)box.put(box.get());^ 1 error這個(gè)代碼看起
7、來(lái)應(yīng)該可以工作,因?yàn)槿〕鲋档念?lèi)型符合放回值的類(lèi)型,然而,編譯器生成(令人困惑的)關(guān)于 “capture#337 of ?” 與 Object 不兼容的 錯(cuò)誤消息。“capture#337 of ?” 表示什么?當(dāng)編譯器遇到一個(gè)在其類(lèi)型中帶有通配符的 變量,比如 rebox() 的 box 參數(shù),它認(rèn)識(shí)到必然有一些 T ,對(duì)這些 T 而言 box 是 Box。它不知道 T 代表什么類(lèi)型,但它可以為該類(lèi)型創(chuàng)建一個(gè)占位符來(lái)指代 T 的類(lèi)型。占
8、位符被稱(chēng)為這個(gè)特殊通配符的捕獲(capture)。這種情況 下,編譯器將名稱(chēng) “capture#337 of ?” 以 box 類(lèi)型分配給通配符。每個(gè)變量聲明中每出現(xiàn)一個(gè)通配符都將獲得一個(gè)不同的捕獲,因此在泛型聲明 foo(Pair x, Pair y) 中,編譯器將給每四個(gè)通配符的捕獲分配一個(gè)不同的名稱(chēng),因?yàn)槿我馕粗念?lèi)型參數(shù)之間沒(méi)有關(guān)系。 錯(cuò)誤消息告訴我們不能調(diào)用 put(),因?yàn)樗荒軝z驗(yàn) put() 的實(shí)參類(lèi)型與其形 參類(lèi)型是否
9、兼容 — 因?yàn)樾螀⒌念?lèi)型是未知的。在這種情況下,由于 ? 實(shí)際表示 “?extends Object” ,編譯器已經(jīng)推斷出 box.get() 的類(lèi)型是 Object,而不是 “capture#337 of ?”。它不能靜態(tài)地檢驗(yàn)對(duì)由占位符 “capture#337 of ?” 所識(shí)別的類(lèi)型而言 Object 是否是一個(gè)可接受的值。捕獲助手 捕獲助手雖然編譯器似乎丟棄了一些有用的信息,我們可以使用一個(gè)技巧來(lái)使編譯器重構(gòu)這些信息,即對(duì)未
溫馨提示
- 1. 本站所有資源如無(wú)特殊說(shuō)明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請(qǐng)下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請(qǐng)聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶(hù)所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁(yè)內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒(méi)有圖紙預(yù)覽就沒(méi)有圖紙。
- 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
- 5. 眾賞文庫(kù)僅提供信息存儲(chǔ)空間,僅對(duì)用戶(hù)上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對(duì)用戶(hù)上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對(duì)任何下載內(nèi)容負(fù)責(zé)。
- 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請(qǐng)與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶(hù)因使用這些下載資源對(duì)自己和他人造成任何形式的傷害或損失。
評(píng)論
0/150
提交評(píng)論