亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb

首頁 > 編程 > Java > 正文

Java 泛型詳解

2019-11-11 06:56:04
字體:
供稿:網(wǎng)友

學(xué)習(xí)java的同學(xué)注意了?。?! 學(xué)習(xí)過程中遇到什么問題或者想獲取學(xué)習(xí)資源的話,歡迎加入Java學(xué)習(xí)交流群,群號碼:183993990  我們一起學(xué)Java!

泛型概述

Java泛型(generics)是JDK 5中引入的一個新特性,允許在定義類和接口的時候使用類型參數(shù)(type parameter)。聲明的類型參數(shù)在使用時用具體的類型來替換。

優(yōu)缺點

從好的方面來說,泛型的引入可以解決之前的集合類框架在使用過程中通常會出現(xiàn)的運行時刻類型錯誤,因為編譯器可以在編譯時刻就發(fā)現(xiàn)很多明顯的錯誤。而從不好的地方來說,為了保證與舊有版本的兼容性,Java泛型的實現(xiàn)上存在著一些不夠優(yōu)雅的地方。當(dāng)然這也是任何有歷史的編程語言所需要承擔(dān)的歷史包袱。后續(xù)的版本更新會為早期的設(shè)計缺陷所累。

舉例

List作為形式參數(shù),那么如果嘗試將一個List的對象作為實際參數(shù)傳進(jìn)去,卻發(fā)現(xiàn)無法通過編譯。雖然從直覺上來說,Object是String的父類,這種類型轉(zhuǎn)換應(yīng)該是合理的。但是實際上這會產(chǎn)生隱含的類型轉(zhuǎn)換問題,因此編譯器直接就禁止這樣的行為。

類型擦除

正確理解泛型概念的首要前提是理解類型擦除(type erasure)。

Java中的泛型基本上都是在編譯器這個層次來實現(xiàn)的。

在生成的Java字節(jié)代碼中是不包含泛型中的類型信息的。使用泛型的時候加上的類型參數(shù),會被編譯器在編譯的時候去掉。這個過程就稱為類型擦除。

如在代碼中定義的List和List等類型,在編譯之后都會變成List。JVM看到的只是List,而由泛型附加的類型信息對JVM來說是不可見的。Java編譯器會在編譯時盡可能的發(fā)現(xiàn)可能出錯的地方,但是仍然無法避免在運行時刻出現(xiàn)類型轉(zhuǎn)換異常的情況。類型擦除也是Java的泛型實現(xiàn)方式與C++模板機(jī)制實現(xiàn)方式之間的重要區(qū)別。

很多泛型的奇怪特性都與這個類型擦除的存在有關(guān)

1.泛型類并沒有自己獨有的Class類對象。比如并不存在List.class或是List.class,而只有List.class。

2.靜態(tài)變量是被泛型類的所有實例所共享的。對于聲明為MyClass的類,訪問其中的靜態(tài)變量的方法仍然是 MyClass.myStaticVar。不管是通過new MyClass還是new MyClass創(chuàng)建的對象,都是共享一個靜態(tài)變量。

3.泛型的類型參數(shù)不能用在Java異常處理的catch語句中。因為異常處理是由JVM在運行時刻來進(jìn)行的。由于類型信息被擦除,JVM是無法區(qū)分兩個異常類型MyException和MyException的。對于JVM來說,它們都是 MyException類型的。也就無法執(zhí)行與異常對應(yīng)的catch語句。

類型擦除的過程

類型擦除的基本過程也比較簡單,首先是找到用來替換類型參數(shù)的具體類。這個具體類一般是Object。如果指定了類型參數(shù)的上界的話,則使用這個上界。把代碼中的類型參數(shù)都替換成具體的類。同時去掉出現(xiàn)的類型聲明,即去掉<>的內(nèi)容。比如T get()方法聲明就變成了Object get();List就變成了List。接下來就可能需要生成一些橋接方法(bridge method)。這是由于擦除了類型之后的類可能缺少某些必須的方法。

實例分析

了解了類型擦除機(jī)制之后,就會明白編譯器承擔(dān)了全部的類型檢查工作。編譯器禁止某些泛型的使用方式,正是為了確保類型的安全性。以上面提到的List和List為例來具體分析:

public void inspect(List<Object> list) {        for (Object obj : list) {                System.out.PRintln(obj);        }        list.add(1); //這個操作在當(dāng)前方法的上下文是合法的。 }public void test() {        List<String> strs = new ArrayList<String>();        inspect(strs); //編譯錯誤 }

這段代碼中,inspect方法接受List作為參數(shù),當(dāng)在test方法中試圖傳入List的時候,會出現(xiàn)編譯錯誤。假設(shè)這樣的做法是允許的,那么在inspect方法就可以通過list.add(1)來向集合中添加一個數(shù)字。這樣在test方法看來,其聲明為List的集合中卻被添加了一個Integer類型的對象。這顯然是違反類型安全的原則的,在某個時候肯定會拋出ClassCastException。因此,編譯器禁止這樣的行為。編譯器會盡可能的檢查可能存在的類型安全問題。對于確定是違反相關(guān)原則的地方,會給出編譯錯誤。當(dāng)編譯器無法判斷類型的使用是否正確的時候,會給出警告信息。

泛型類

容器類應(yīng)該算得上最具重用性的類庫之一。先來看一個沒有泛型的情況下的容器類如何定義:

public class Container {    private String key;    private String value;    public Container(String k, String v) {        key = k;        value = v;    }    public String getKey() {        return key;    }    public void setKey(String key) {        this.key = key;    }    public String getValue() {        return value;    }    public void setValue(String value) {        this.value = value;    }}

Container類保存了一對key-value鍵值對,但是類型是定死的,也就說如果我想要創(chuàng)建一個鍵值對是String-Integer類型的,當(dāng)前這個Container是做不到的,必須再自定義。那么這明顯重用性就非常低。

當(dāng)然,我可以用Object來代替String,并且在Java SE5之前,我們也只能這么做,由于Object是所有類型的基類,所以可以直接轉(zhuǎn)型。但是這樣靈活性還是不夠,因為還是指定類型了,只不過這次指定的類型層級更高而已,有沒有可能不指定類型?有沒有可能在運行時才知道具體的類型是什么?

所以,就出現(xiàn)了泛型。

public class Container<K, V> {    private K key;    private V value;    public Container(K k, V v) {        key = k;        value = v;    }    public K getKey() {        return key;    }    public void setKey(K key) {        this.key = key;    }    public V getValue() {        return value;    }    public void setValue(V value) {        this.value = value;    }}

在編譯期,是無法知道K和V具體是什么類型,只有在運行時才會真正根據(jù)類型來構(gòu)造和分配內(nèi)存??梢钥匆幌卢F(xiàn)在Container類對于不同類型的支持情況:

public class Main {    public static void main(String[] args) {        Container<String, String> c1 = new Container<String, String>("name", "findingsea");        Container<String, Integer> c2 = new Container<String, Integer>("age", 24);        Container<Double, Double> c3 = new Container<Double, Double>(1.1, 2.2);        System.out.println(c1.getKey() + " : " + c1.getValue());        System.out.println(c2.getKey() + " : " + c2.getValue());        System.out.println(c3.getKey() + " : " + c3.getValue());    }}
輸出:name : findingseaage : 241.1 : 2.2

泛型接口

在泛型接口中,生成器是一個很好的理解,看如下的生成器接口定義:

public interface Generator<T> {    public T next();}然后定義一個生成器類來實現(xiàn)這個接口:public class FruitGenerator implements Generator<String> {    private String[] fruits = new String[]{"Apple", "Banana", "Pear"};    @Override    public String next() {        Random rand = new Random();        return fruits[rand.nextInt(3)];    }}調(diào)用:public class Main {    public static void main(String[] args) {        FruitGenerator generator = new FruitGenerator();        System.out.println(generator.next());        System.out.println(generator.next());        System.out.println(generator.next());        System.out.println(generator.next());    }}輸出:BananaBananaPearBanana

泛型方法

一個基本的原則是:無論何時,只要你能做到,你就應(yīng)該盡量使用泛型方法。也就是說,如果使用泛型方法可以取代將整個類泛化,那么應(yīng)該有限采用泛型方法。下面來看一個簡單的泛型方法的定義:

public class Main {    public static <T> void out(T t) {        System.out.println(t);    }    public static void main(String[] args) {        out("findingsea");        out(123);        out(11.11);        out(true);    }}

可以看到方法的參數(shù)徹底泛化了,這個過程涉及到編譯器的類型推導(dǎo)和自動打包,也就說原來需要我們自己對類型進(jìn)行的判斷和處理,現(xiàn)在編譯器幫我們做了。這樣在定義方法的時候不必考慮以后到底需要處理哪些類型的參數(shù),大大增加了編程的靈活性。

再看一個泛型方法和可變參數(shù)的例子:

public class Main {    public static <T> void out(T... args) {        for (T t : args) {            System.out.println(t);        }    }    public static void main(String[] args) {        out("findingsea", 123, 11.11, true);    }}

通配符與上下界

在使用泛型類的時候,既可以指定一個具體的類型,如List就聲明了具體的類型是String;也可以用通配符?來表示未知類型,如List

類型系統(tǒng)

在Java中,大家比較熟悉的是通過繼承機(jī)制而產(chǎn)生的類型體系結(jié)構(gòu)。比如String繼承自O(shè)bject。根據(jù)Liskov替換原則,子類是可以替換父類的。當(dāng)需要Object類的引用的時候,如果傳入一個String對象是沒有任何問題的。但是反過來的話,即用父類的引用替換子類引用的時候,就需要進(jìn)行強(qiáng)制類型轉(zhuǎn)換。編譯器并不能保證運行時刻這種轉(zhuǎn)換一定是合法的。這種自動的子類替換父類的類型轉(zhuǎn)換機(jī)制,對于數(shù)組也是適用的。 String[]可以替換Object[]。但是泛型的引入,對于這個類型系統(tǒng)產(chǎn)生了一定的影響。正如前面提到的List是不能替換掉List的。

引入泛型之后的類型系統(tǒng)增加了兩個維度:

一個是類型參數(shù)自身的繼承體系結(jié)構(gòu),另外一個是泛型類或接口自身的繼承體系結(jié)構(gòu)。第一個指的是對于 List和List這樣的情況,類型參數(shù)String是繼承自O(shè)bject的。而第二種指的是 List接口繼承自Collection接口。對于這個類型系統(tǒng),有如下的一些規(guī)則:

相同類型參數(shù)的泛型類的關(guān)系取決于泛型類自身的繼承體系結(jié)構(gòu)。

即List是Collection 的子類型,List可以替換Collection。這種情況也適用于帶有上下界的類型聲明。

當(dāng)泛型類的類型聲明中使用了通配符的時候, 其子類型可以在兩個維度上分別展開。如對Collection

泛型的命名規(guī)范

為了更好地去理解泛型,我們也需要去理解java泛型的命名規(guī)范。為了與java關(guān)鍵字區(qū)別開來,java泛型參數(shù)只是使用一個大寫字母來定義。各種常用泛型參數(shù)的意義如下:

E — Element,常用在java Collection里,如:List,Iterator,SetK,V — Key,Value,代表Map的鍵值對N — Number,數(shù)字T — Type,類型,如String,Integer等等S,U,V etc. – 2nd, 3rd, 4th 類型,和T的用法一樣

學(xué)習(xí)Java的同學(xué)注意了?。?! 學(xué)習(xí)過程中遇到什么問題或者想獲取學(xué)習(xí)資源的話,歡迎加入Java學(xué)習(xí)交流群,群號碼:183993990  我們一起學(xué)Java!


發(fā)表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發(fā)表
欧美男人天堂网| 黄在线免费观看| 国产又黄又猛又爽| 精品国产一区二区三区久久久蜜月| 久久国产精品免费精品3p| 在线中文字幕-区二区三区四区| 五月婷婷综合激情网| 高清一区二区三区视频| 超鹏97在线| 捆绑变态av一区二区三区| 中国xxxx视频播放50| 久久久久久无码精品大片| 国产精品午夜剧场| 蜜桃视频一日韩欧美专区| 97碰碰碰免费公开在线视频| 天天久久综合网| 国产精品天天看| 视频一区二区欧美| av片在线免费看| 精品国免费一区二区三区| 日本不卡一区二区三区视频| 亚洲精品一卡二卡三卡四卡| 麻豆av免费在线观看| 91在线精品秘密一区二区| 国产精品久久久久久免费| 成人网址在线观看| 国产午夜精品久久久久久免费视| 91精品久久久久久久蜜月| 亚洲欧美日韩综合网| 91精品国产经典在线观看| 日韩毛片在线看| 在线观看成年人视频| 99re6热在线精品视频播放| 99免费精品在线| 国产经典自拍视频在线观看| 97免费高清电视剧观看| 在线免费av导航| 日本在线高清视频一区| 少妇精品导航| 中文字幕在线播放一区二区| 成人啪啪18免费游戏链接| 欧美大片免费看| 欧美高清性xxxxhd| 青青青国产在线观看| 黄色网免费观看| 成人黄动漫网站免费| 欧美日韩亚洲精品内裤| 麻豆免费在线观看视频| 天天影视天天精品| 日本在线中文字幕一区二区三区| 性感美女视频一二三| 91亚洲精品视频在线观看| 国产成人精品免高潮费视频| 国产乱淫a∨片免费观看| 亚洲精品资源| 日韩精品中文字幕在线一区| 日本在线视频观看| 日本一二三不卡| 亚洲国产成人av| 六月丁香激情网| 7m精品福利视频导航| 久久av免费| 久久er热在这里只有精品66| 黄色软件视频在线观看| 成人午夜免费在线| 国产精品视频一区二区三区四蜜臂| 午夜国产一级| 国产剧情麻豆剧果冻传媒视频免费| 欧美精品v日韩精品v韩国精品v| 浮生影视网在线观看免费| 国产亚洲va综合人人澡精品| 色综合一区二区三区| 青青草久久网络| 韩国视频一区二区三区| 噜噜噜在线观看播放视频| 波多野结衣中文字幕一区二区三区| 国产精品自拍三区| 天天爽夜夜爽夜夜爽精品| 亚洲人成影院在线观看| 6699久久国产精品免费| 国产伦理在线观看| 国产成人精品综合| 欧美h视频在线观看| 蜜桃久久精品一区二区| 一分钟免费观看视频播放www| 亚洲图片第一页| 亚洲色图27p| av国产精品| 欧美日韩成人在线视频| 亚洲人亚洲人色久| 色综合网站在线| 国产日韩一区二区在线观看| 国产探花在线免费观看| 欧美日韩国产不卡| 香蕉视频一区二区| 亚洲成人免费电影| 久久全国免费久久青青小草| 99国内精品久久久久| 国产精品无码AV| 中文字幕精品网| 女性生殖扒开酷刑vk| 99久久99久久免费精品蜜臀| 国产主播精品在线| 久国内精品在线| 久久久人成影片一区二区三区在哪下载| 自拍偷拍第1页| 一本色道久久88亚洲综合88| 国产尤物视频在线| 亚洲美女视频在线| 国产传媒一区| 久久国产精品高清| 制服国产精品| 91精品国产麻豆国产在线观看| 国产免费一区视频观看免费| 亚洲 日韩 国产第一区| h小视频在线观看网| 久久免费看视频| 狠狠躁日日躁夜夜躁av| 美女性感视频久久| 久久久久久伊人| 亚洲天堂中文网| 国产精品密蕾丝视频下载| 欧美一区二区播放| 最新欧美色图| 免费观看国产精品视频| 在线观看免费的av| 性生交大片免费看女人按摩| 大荫蒂欧美视频另类xxxx| 亚洲人成伊人成综合网久久久| 青青草原在线免费观看| 久久久久无码精品| 国产欧美亚洲一区| 超碰在线免费公开| 国产成人美女视频| 中文字幕乱伦视频| 夜夜嗨一区二区| 成人黄色av网| 成人黄色免费网| 国产91av在线播放| 欧美日韩一区二| av男人的天堂在线| a天堂在线观看| 欧美乱大交xxxxx免费| 久草视频在线看| 国产精品一区高清| 巨乳诱惑日韩免费av| 午夜精品一二三区| 国产情侣久久久久aⅴ免费| 日本不卡视频一区二区| 久久视频在线直播| 丰满亚洲少妇av| 99re66热这里只有精品8| 日本一本不卡| 国产精品热久久| 亚洲综合日韩中文字幕v在线| 国产精品熟妇一区二区三区四区| 综合国产精品| 日本一本在线视频| 午夜影院免费视频| 风间由美性色一区二区三区| 国产一区二区三区在线观看| 致1999电视剧免费观看策驰影院| 欧美日韩精品免费观看视频完整| 午夜精品视频一区| 四虎永久在线观看免费网站网址| 色诱色偷偷久久综合| 成看片vvv222| 精品久久久无码中文字幕| 欧美电影免费看| 日日夜夜精品视频免费观看| 亚洲欧洲国产视频| 国产男女猛烈无遮挡91| 精品动漫一区二区三区| 国产三级日本三级在线播放| 亚洲欧美一二三区| 亚洲综合大片69999| 亚洲精品中文在线观看| 日韩激情网站| 免费看国产片在线观看| 欧美激情18p| 精品无人区乱码1区2区3区在线| 97精品国产97久久久久久春色| 日本高清免费不卡视频| 大奶在线精品| 国产cdts系列另类在线观看| 久久综合伊人77777麻豆| 成人eeuss影院在线观看| 国产欧美一区二区三区不卡高清| 午夜久久资源| 欧美亚洲禁片免费| 欧美亚洲精品日韩| 99久久精品免费看国产免费软件| 成人福利影院| 美女扒开腿让男人桶爽久久软| 国产精品自拍第一页| 日韩一区日韩二区| 欧美bbbbbbbbbbbb精品| 久在线观看福利视频| 国产欧美视频在线观看| 97精品在线播放| 在线人成日本视频| 国内精品久久久久久中文字幕| 在线成人av电影| 成人一区二区不卡免费| 日韩欧美一区二区在线观看| 在哪里可以看毛片| 欧美激情偷拍| 亚洲三级电影全部在线观看高清| 色哟哟中文字幕| 天天影视久久综合| 亚洲毛片一区| 网红女主播少妇精品视频| 亚洲精品久久久久久久久久久久久| 亚洲国产精品久久久久婷婷软件| 色婷婷av一区二区三| 国产在线观看a| 天堂网在线观看| 影院免费视频| eeuss性xxxxxx电影| www.中文字幕av| 欧美主播福利视频| 免费萌白酱国产一区二区三区| 91免费观看网站| 亚洲精品电影在线| 色啪免费观看视频| 啦啦啦高清在线观看www| 99久久一区二区| 欧美性色黄大片手机版| 国产高中女学生第一次| 久久综合久久鬼| 黄污视频在线观看| 欧美极品在线播放| 亚洲国产一区二区三区四区| 欧美年轻男男videosbes| 亚洲经典视频在线观看| 国产日韩欧美在线播放| 久久久久久av无码免费看大片| 九九热在线视频免费观看| 成人亚洲欧美一区二区三区| 成人福利一区| 自拍偷拍一区二区三区四区| www欧美激情| 日韩成人影视| japanese色国产在线看视频| 亚洲精品自拍偷拍| 日韩美女天天操| 一级在线观看| 国产视频一二三区| 最新日本在线观看| 国产精品亚洲d| 99久久无色码| 亚洲一区二区三区视频播放| 激情欧美一区二区三区中文字幕| 99久久99久久精品国产片果冰| 亚洲性图第一页| bl动漫在线观看| 日韩三级影视| ass白嫩白嫩的小美女| 日韩精品一二区| 一区二区三区在线观看欧美| 青青草精品视频在线观看| 亚洲综合日韩| 久久久xxx| av成人免费在线| 国产精品.xx视频.xxtv| 免费日本视频一区| 国产高清视频免费在线观看| 欧美日韩一区国产| 一区二区视频免费在线观看| 国产精品一区二区女厕厕| 美女裸体自慰在线观看| 日本一区二区三级电影在线观看| 日韩激情啪啪| 久久精品亚洲一区| 久久久国产精品人人片| 亚洲性夜色噜噜噜7777| 国产日韩在线一区| 在线观看av每日更新免费| 亚洲国产网址| 日本黄色女人| 国产免费一区二区三区视频| www.av免费| 精品网站999www| 日本亚洲欧美在线| 国产调教视频在线观看| 日韩黄色在线视频| 丝袜脚交一区二区| 国产三区在线视频| 男女曰b免费视频| 后入内射欧美99二区视频| 欧区一欧区二欧区三| www.555国产精品免费| 亚洲天堂激情| 日韩欧美卡一卡二| 欧美亚洲丝袜| 人妖精品videosex性欧美| 在线这里只有精品| 国产亚洲精品久久飘花| 美日韩精品免费观看视频| 狠狠色综合一区二区| 日韩黄色a级片| 呦视频在线一区二区三区| 亚洲女人天堂视频| 国产免费的av| 欧美精品亚洲精品| 免费男女羞羞的视频网站中文字幕| 欧美视频在线播放一区| 色呦呦网站一区| 亚洲成a人片77777在线播放| 中文资源在线播放| jizzjizz欧美69巨大| 亚洲女人天堂av| 亚洲黄色在线网站| 国内精品一区二区三区四区| 国产一区二区美女| 少妇高潮毛片色欲ava片| 日韩欧美国产综合在线一区二区三区| www污污在线| 精品人妻伦一区二区三区久久| 日韩一区二区av| 精品无码人妻一区二区免费蜜桃| 久久视频精品在线| 亚洲欧美综合网| 日韩美女爱爱视频| 精品视频一二三| 老司机午夜精品视频在线观看| 国产手机视频精品| 国模私拍一区二区国模曼安|