| 註冊 | 登入 | 全文檢索 | 排行榜 |
|
» JavaWorld@TW
» Java SE 討論區
|
![]() ![]() ![]()
|
| 本主題所含的標籤 |
| 作者 | Generics 簡介 [精華] | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
jocosn
![]() ![]() ![]() ![]()
發文: 99 積分: 5 |
至於為什麼貼在這區,不貼在新手區?因為這區的 2 位版主很厲害,可能會提供更多進一步的解說。就醬。 紅色斜體字在程式碼實作時須自行替換。橘色 [] 表示非必要可省略。 請注意,如果你直接拷貝程式碼準備跑跑看,你必須將全型空白(排版用)轉為半形空白。請使用 IDE 工具提供的替代功能。 ********************************************************* 泛型(Generics) 1. Generics 可提供 compile-time type 檢查。 2. 泛型的使用: ◇ 類別 (註:介面泛型類似類別泛型,此處不作介紹) •定義泛型 ![]() A> [class-modifiers] class GenericsName<T1 [, T2, T3, ...]> { ...... } 泛型由泛型名稱(generic type name)、角括號 "<>"、包含在角括號內的型態參數(type parameter)組成。 在角括號 "<>" 內的型態參數( Tx ) 須為某種參考型態。 [範例]
B> 泛型類別(/介面)可被繼承(/實作),子類別(實作介面)無論是否宣告父類別(介面)的型態參數皆會繼承型態參數,並且可以宣告新的型態參數。 子類別若沒有宣告父類別(/介面)的全部型態參數,則繼承的型態參數會自動變為 Object 型別。 (註:參考偶像良葛格的筆記) (以上這段請見下面 Duncan版主的更正) [範例]
[範例]
•宣告/建立泛型物件(Instantiating a Generic Type) ![]() A> 宣告泛型物件 1> concrete parameterized type 須使用泛型名稱(generic type name),後面加上角括號"<>",角括號"<>" 內須以 class 或 interface 名稱取代泛型宣告的型態參數(type parameter)來指定泛型真正的使用型態。 [範例] concrete parameterized type
[範例]
2> wildcard type & bounded wildcard a> wildcard type (通配型) 角括號內若使用問號 "?" 而不是 class 或 interface 名稱,表示宣告泛型型別為通用型別,可使用任何的參考型態。 "?" 表示未知型態(unknown type)。 b> bounded wildcard (有限制的通配型) wildcard type 可限制型別的範圍(bounds)。 使用 extends 關鍵字可指定欲使用的型態必須是某個型別(介面或類別)或其衍生型別。 使用 super 關鍵字指定使用某個型別(介面或類別)及其父型別。 使用 "&" 符號可作多重限制(Multiple bounds)。 [範例]
[範例] can create a variable of type Matrix<Integer> or Matrix<Float>,
[範例]
[範例]
3> raw type 宣告泛型物件只使用泛型名稱(generic type name),則預設會使用 Object 型別,使用此類物件須自行轉換型態,且編譯器會發出 warning 訊息。 [註] 原生類型:raw type,指未使用泛型,如 Collection、ArrayList 等 Java 5 之前的舊形式,或指僅使用泛型名稱(generic type without type arguments)。 Java Language Specification 第 3 版指出以後的版本可能會禁止使用 raw type。 [範例]
B> 建立泛型物件須使用 new 關鍵字,並指定型態參數的值(values of the type parameters)。此種指定值的型態參數稱為 parameterized type。 [範例]
[範例]
◇ methods 使用泛型 [MethodModifiers] [TypeParameters] ResultType MethodName(...) [throws ....] ;|{ ... } 不論 class(interface) 是否宣告泛型,methods 皆可使用泛型。 [範例]
[範例]
[範例]
[範例]
3. 泛型使用的注意事項 ![]() ![]() A> static members 內不能使用 type parameters [範例]
B> primitive types 不能使用在泛型 C> "Naked" type parameters (指不包括角括號的型態參數,如 C<T>,指的是 T ) 不能做的事: 不能用在鑄型(casts)、instanceof、或 new 運算上。 不能使用在定義 class 時的 implements 或 extends 子句內 不能用來建立物件,也不能用作父類型 (class Foo<T> extends T),不能用於類別實字(class literal)。 [範例]
[範例]
D> 異常型態(exception type)、列舉(enumeration)或匿名內部類(anonymous inner class)不能使用型態參數(type paramemter)。 type variables 雖不允許使用在 catch 子句內,但可用在 methods 利用 throws 所丟出的例外清單中。 如果 generic class 為 Throwable 的 subclass(直間或間接),會產生 compile-time error。因為 throw/catch mechanism 只能作用在 non-generic classes 上。 [範例]
E> 泛型不是 covariant 如果 MySub 是 MySuper 的子類型,當 MyG 作泛型類別宣告時,MyG<MySub>不是 G<MySuper>的子型態(subtype)。 例 List<Object> 不是 List<String> 的父型態。 [範例]
F> 通配泛型(type wildcards) 雖可檢索元素(retrieve elements)與移除元素,但不能增加元素。 [範例]
G> 泛型在進行編譯時會進行 erasure 的過程,會刪除所有的泛型資訊。 [範例] 以下的範例會產生錯誤:duplicate class
[範例] 以下的範例會產生錯誤:name crash, have the same erasure
[範例]
[範例]
[範例]
[範例] parameterized type 可 cast 為 raw type
[範例] Breaking type safety with reflection
H> 陣列無法使用泛型,除非是一個通配符類型(unbounded wildcard)。 可以宣告型態變數(concrete parameterized type)的陣列,但是不能使用 new 建立陣列。如 new T[100],因為型態變數會被 erasure。因此你只能指派此種陣列為 null。 或是使用反射機制和類別實字(ClassName.class)解決。 [範例]
*********************************************** 看完上面的文章之後,想測驗自己對 Generics 的了解,可以試試看下面的小測驗 http://www.grayman.de/quiz/java-generics-en.quiz http://www.langer.camelot.de/GenericsFAQ/JavaGenericsFAQ.html#Fundamentals%20of%20Java%20Generics *********************************************** 參考 Generics FAQs 了解泛型 Generic Types, Part 1 Erasure and Accidental Compile-Time Conflicts Not wild enough Wildcards in the Generics Specification http://www.devx.com/Java/Article/16024 http://java.sun.com/j2se/1.5/pdf/generics-tutorial.pdf --Sun 的教學 http://www.davidflanagan.com/blog/000027.html --Generics Glossary 無痛苦 generics http://www-106.ibm.com/developerworks/java/library/j-djc02113.html http://www-106.ibm.com/developerworks/java/library/j-djc03113.html http://www-106.ibm.com/developerworks/java/library/j-djc04093.html http://www-106.ibm.com/developerworks/java/library/j-djc05133.html |
| 作者 | Re:Generics 簡介 [Re:jocosn] |
jocosn
![]() ![]() ![]() ![]()
發文: 99 積分: 5 |
不知道有沒有人願意對 "wildcard capture" 和 "陣列使用泛型" 這 2 方面做一些補充? |
| 作者 | Re:Generics 簡介 [Re:jocosn] |
jocosn
![]() ![]() ![]() ![]()
發文: 99 積分: 5 |
有幾點要注意的地方 http://mindview.net/WebLog/log-0058 1. .... the erasure only happens inside the class or method. At the boundaries – when the object is being passed in or out – the type- checking actually happens. 2. There is lots of published misinformation about this fact. For example, a fair number of people have firmly asserted that erasure allows Java 5.0 code to run under JDK 1.4. Neal Gafter has stated that this is incorect. 至於為什麼 Java 使用 erasure ?大師的解答是它無法回答這個問題: ...so far I haven't been able to answer the question: what made erasure necessary?. 註:C# 對泛型的做法是採用 reification,該篇中也提到: ... no need to recompile .NET 1.0 (or 1.1) libraries in order to run them on .NET 2.0. The old binaries continue to work. |
| 作者 | Re:Generics 簡介 [Re:jocosn] |
jocosn
![]() ![]() ![]() ![]()
發文: 99 積分: 5 |
附上 PDF 檔案,方便下載閱讀。 中文字使用 "文鼎粗黑" 字體,請自行安裝。 因為使用細明體字體太細,PDF 檔案看起來很累。 我不會包字型到 PDF 檔案。 考慮到個人不想使用 PDF 檔案格式,另有 EXCEL 格式(使用 OFFice 2003 編輯)。 2 個合壓在一起,方便個人加註心得與重點,有需要請自取。 或是到這個網站自取 pdf 檔案 http://www.freewebtown.com/jocosn/pdf_download.html HTML 線上觀看(有顏色區分,較易閱讀) http://www.freewebtown.com/jocosn/java_tiger.htmll java_tiger.zip (315.47k)
|
| 作者 | Re:Generics 簡介 [Re:jocosn] |
Mabel
![]() ![]() ![]() ![]()
發文: 13 積分: 0 |
thanks for sharing your experiences! howerver, Caterpillar's notes about Generics is much easier for the beginners. 我是一只小鸟 菜菜的小鸟 |
| 作者 | Re:Generics 簡介 [Re:Mabel] |
jocosn
![]() ![]() ![]() ![]()
發文: 99 積分: 5 |
Mabel wrote: This note is summary of generics for review, not just for beginner. 如果是初學者,必須仔細看這個 topic,因為初學者必須加入很多口旁白和解釋。這樣的 topic 不適合貼在這樣的論壇上。因為 generics 的相關說明太多。 所以我的建議是,你看過這個 topic 相關的英文網站、良葛大文章後,再來看這個 topic 的內容,或作為日後複習。 這裡有篇文章,先看過,可加強了解為什麼要有泛型?以及它能帶給你什麼。 http://www.digitimes.com.tw/n/article.asp?id=24E76ABF6D22E5B248256F72000B4C6A |
| 作者 | Re:Generics 簡介 [Re:jocosn] | ||||
Duncan
街友 JaJa 版主
發文: 7594 積分: 39 |
jocosn wrote: 子類別若無宣告 type variable(該 class 不是 generics type),何謂繼承 type variable? 若子類別有宣告 type variables,這些 type variables 跟父類別 type variables 無關。 在子類別宣告中,指定基底類別的部分是 parameterized type。 給我 貓咪 其餘免談 我要效法葛屁老師,我承認了,我是蘿莉控。 |
| 作者 | Re:Generics 簡介 [Re:jocosn] |
jiangshachina
Hi, Java! ![]() ![]() ![]() ![]()
發文: 527 積分: 1 |
E应该是Element;T就是Type。 这些字符都是惯例的用法,理论上也可以用其它字符替代。 a cup of Java, cheers! 同是Java爱好者,相逢何必曾相识! |
| 作者 | Re:Generics 簡介 [Re:jocosn] |
riceandabc
![]() ![]() ![]() ![]()
發文: 10 積分: 0 |
ding |
| 作者 | Re:Generics 簡介 [Re:jocosn] |
serialeasy
![]() ![]() ![]() ![]()
發文: 13 積分: 0 |
非常有幫助,太謝謝了 java comm,Java USB,RXTX rs232-rs485/rs422 converter,usb to rs232/rs485/rs422 keeping communicate fast and easy http://www.hexin-tech.com.cn/ |
| 作者 | Re:Generics 簡介 [Re:jocosn] |
koji
秒速5センチメートル 站長
發文: 7580 積分: 19 |
Java Generics FAQs - Frequently Asked Questions http://www.angelikalanger.com/GenericsFAQ/JavaGenericsFAQ.html 看到有人提供的連結 koji Facebook上的TWJUG社團,歡迎加入 |
| 作者 | Re:Generics 簡介 [Re:jocosn] |
ycdta
![]() ![]() ![]() ![]()
發文: 18 積分: 0 |
jocosn wrote: 這個網站就是的嗎 我是個初學者哦 誰 能告訴我啊 Java-certification Java-certification |
| 作者 | Re:Generics 簡介 [Re:jocosn] |
leonboy
![]() ![]() ![]() ![]()
發文: 6 積分: 0 |
Thanks for your sharing. 交接了別人的專案, 其中用了很多 Generics 以及其他 skills, 您的文章對 fast-track purpose 的我很有用.
LeonBoy...來自小蟹的移動城堡 ^^ |
| » JavaWorld@TW » Java SE 討論區 |
![]() ![]() ![]()
|
已讀文章 新的文章 被刪除的文章 |