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

首頁 > 開發 > Java > 正文

Java泛型定義與用法實例詳解

2024-07-14 08:42:10
字體:
來源:轉載
供稿:網友

本文實例講述了Java泛型定義與用法。分享給大家供大家參考,具體如下:

1. 泛型的由來

先看如下代碼:

import java.util.List;import java.util.ArrayList;public class TestGeneric {    @SuppressWarnings({ "rawtypes", "unchecked" })    public static void main(String[] args) {        List list = new ArrayList();        list.add(1);        list.add("1");        list.add(new Object());        System.out.println(list);        // 取值        Integer var1 = (Integer) list.get(0);        String var2 = (String) list.get(1);        Object var3 = list.get(2);        System.out.println(var1 + " " + var2 + " " + var3);    }}

運行結果:

[1, 1, java.lang.Object@1db9742]
1 1 java.lang.Object@1db9742

這段代碼很簡單,將整形、字符串、對象放進list集合中,然后逐一取出??梢钥闯觯捎贚ist接口在定義時并不知道元素的類型,因此默認為Object,即任意類型元素進入list集合后都會自動裝箱。而取值的過程更為復雜,所有取得的值都是裝箱后的Object對象,必須得知道每一個元素的初始類型才能拆箱。一般使用集合的時候,集合的元素往往都是具有共同特征的,比如同屬于一類的----那么,如果一開始限定了list集合元素的類型,那么就可避免上述不規范操作。代碼如下,

import java.util.List;import java.util.ArrayList;public class TestGeneric {    @SuppressWarnings("unused")    public static void main(String[] args) {        List<String> list = new ArrayList<String>();        // list.add(1);//報錯        // list.add(new Object());//報錯        list.add("1");        // 取值        String var1 = list.get(0);// 無需轉換    }}

如此一來,便有了泛型集合的說法。實際上,查閱List接口的Api會發現,List接口正是泛型接口,它可以接受一個類型參數E,若不傳遞參數,則默認是Object類型。

2. 泛型類型的繼承關系

有如下功能的代碼,實現打印任意集合的元素:

import java.util.List;import java.util.ArrayList;import java.util.Collection;public class TestGeneric{    //打印任意集合元素    public void print(Collection<Object> c){     System.out.println(c);    }    public static void main(String[] args){     List<String> list=new ArrayList<String>();     new TestGeneric().print(list); }}

輸出:

TestGeneric.java:11: 無法將 TestGeneric 中的 print(java.util.Collection<java.lang.Object>) 應用于 (java.util.List<java.lang.String>)
   new TestGeneric().print(list);
                    ^
1 錯誤

很明顯,意思就是傳遞的參數類型不匹配。難道String不是繼承自Object的嗎?沒錯,String是繼承自Object的,但是List<String>List<Object>是截然不同的兩個類型,兩者之間沒有任何繼承關系。那如果真的要實現上面的功能,該如何呢?

2.1 類型通配符

import java.util.List;import java.util.ArrayList;import java.util.Collection;public class TestGeneric {    // 打印任意集合元素    public void print(Collection<?> c) {        System.out.println(c);    }    public static void main(String[] args) {        List<String> list = new ArrayList<String>();        new TestGeneric().print(list);    }}

程序正常執行,這里的?表示一個未知類型,這個未知類型與Object不同,List<?>代表了所有的List<類型>的父類。

2.2 泛型方法

不只有通配符可以解決泛型繼承的問題,若將上面的方法定義為泛型方法也具有同樣的效果:

import java.util.List;import java.util.ArrayList;import java.util.Collection;public class TestGeneric {    // 打印任意集合元素    public <T> void print(Collection<T> c) {        System.out.println(c);    }    public static void main(String[] args) {        List<String> list = new ArrayList<String>();        new TestGeneric().print(list);    }}

泛型方法的定義形式如下,

修飾符 <T,E> 返回值 方法名(形參)

其中<T,E>在修飾符的后面做為類型定義,為方法指明形參中需要用到的T,E類型是來自哪里。既然泛型方法和類型通配符都可以實現泛型中的繼承,那么有什么區別?

2.3 泛型方法和通配符的區別

看如下代碼:

import java.util.List;import java.util.ArrayList;import java.util.Collection;public class TestGeneric {    // 打印任意集合元素    public <E, T extends E> void print(Collection<T> c1, Collection<E> c2) {        System.out.println(c1);        System.out.println(c2);    }    public static void main(String[] args) {        List<Father> list1 = new ArrayList<Father>();        List<Father> list2 = new ArrayList<Father>();        new TestGeneric().print(list1, list2);// 傳2個father類型        List<Child> list3 = new ArrayList<Child>();        List<Father> list4 = new ArrayList<Father>();        new TestGeneric().print(list3, list4);// T為child,E為father        List<Father> list5 = new ArrayList<Father>();        List<Child> list6 = new ArrayList<Child>();        new TestGeneric().print(list5, list6);// T為father,E為child,報錯    }}class Father {}class Child extends Father {}class Other {}

上述泛型方法在定義T,E時已經指明了關系:T是E的子類,所以在傳遞參數的時候,T要么是E的子類,要么就是E本身,所以在傳遞關系不小心變為E exends T時,在第三次調用方法時報錯了。而如果把上述代碼換成?通配符的話,則不具有如此強的限定關系。

總之,泛型方法和?通配符都可以實現未知類型的繼承,但是泛型方法主要強調多個未知類型之間的依賴關系。如果只是單純用作成為一個通用類型的父類這一功能的話,兩者都可以實現,反而?通配符較為簡潔明了。

2.4 泛型參數上、下限的注意

看如下代碼:

import java.util.List;import java.util.ArrayList;import java.util.Collection;public class TestGeneric {    // 復制集合并返回原始集合的最后一個元素    public <T> T copy(Collection<T> des, Collection<? extends T> src) {        T lastElement = null;        for (T t : src) {            lastElement = t;            des.add(t);        }        return lastElement;    }    public static void main(String[] args) {        List<Number> des = new ArrayList<Number>();        List<Integer> src = new ArrayList<Integer>();        src.add(new Integer(1));        Integer lastElement = new TestGeneric().copy(des, src);//        System.out.println(lastElement.getClass());    }}

輸出:

TestGeneric.java:18: 不兼容的類型
找到: java.lang.Number
需要: java.lang.Integer
Integer lastElement= new TestGeneric().copy(des,src);//
                                              ^
1 錯誤

當調用完copy方法后,系統比對發現T類型為Number,?類型為Integer。所以函數返回的T類型是Number了,所以根本不兼容Integer。要修改上面的代碼,有倆個辦法,

方法1:

改為

Number lastElement=new TestGeneric().copy(des,src);

分析代碼可以得出,?為T的子類,在方法中T=lastElement這句表現為多態,雖然返回的是T類型,但是多態的表現為?類型,即Interger類型,調用lastElement.getClass()也可發現返回的是java.lang.Integer類型,說明此處編譯類型為T類型,實際運行類型為?類型。這就好比如下多態轉換,

Father f=new Child();Child c=f;//此處一定報錯,類型不兼容

雖然f的多態表現為子類Child,但是上面一句連語法檢測都過不了。這也就是為什么上面Integer不能兼容Number的原因了。

方法2:

改為

public <T> T copy(Collection<? super T> des,Collection<T> src)

這樣一來,?類型變為了父類,T類型變為了子類,于是在方法中返回的T類型對象,即lastElement就不具有多態性了。泛型中的上下限是很有學問的,每次看源碼時都會琢磨很久,但還是會在浩瀚的接口+泛型的設計中昏迷,這種設計真的完全是為了突出面向對象的特性,以后慢慢琢磨吧。

從這也再次可以看出?通配符在處理具有依賴關系的泛型方法中,顯得過于靈活而會導致一些潛在的隱患。

希望本文所述對大家java程序設計有所幫助。


注:相關教程知識閱讀請移步到JAVA教程頻道。
發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb
性色av香蕉一区二区| 国产va免费精品高清在线| 日韩69视频在线观看| 亚洲欧洲中文天堂| 国产精品ⅴa在线观看h| 欧美三级欧美成人高清www| 国产精品海角社区在线观看| 亚洲欧洲国产一区| 欧美xxxx18国产| 日韩精品视频中文在线观看| 精品动漫一区二区| 亚洲最大av网| 亚洲一区二区三区久久| 色综合久久天天综线观看| www.午夜精品| 亚洲www在线观看| 亚洲精品永久免费精品| 日韩欧美有码在线| 精品久久久久久久久久久久久| 亚洲精品国产精品国自产在线| 2021久久精品国产99国产精品| 日韩黄色av网站| 欧美第一淫aaasss性| 久久色免费在线视频| 久久在线精品视频| 国产一区二区三区在线视频| 亚洲性生活视频| 亚洲欧美日韩精品久久奇米色影视| 亚洲第一福利网站| 久久久999成人| 自拍亚洲一区欧美另类| 国产精品免费视频久久久| 国产日韩在线看| 亚洲欧美精品在线| 色偷偷噜噜噜亚洲男人的天堂| 国产91色在线免费| 久久久久久久91| 欧美性少妇18aaaa视频| 2019中文字幕在线| 一区二区亚洲精品国产| 国产精品久久久久久久久久久久久久| 亚洲欧洲免费视频| 插插插亚洲综合网| 97香蕉久久夜色精品国产| 97久久国产精品| 亚洲经典中文字幕| 亚洲理论在线a中文字幕| 欧美一级高清免费| 日韩精品在线视频观看| 日韩一区二区av| 免费av在线一区| 中文字幕无线精品亚洲乱码一区| 九九九久久国产免费| 第一福利永久视频精品| 日韩av中文字幕在线免费观看| 亚洲在线视频福利| 欧美成人精品激情在线观看| 欧美亚洲在线播放| 欧美激情va永久在线播放| 久久久久久久国产精品| 国产亚洲精品久久久| 日韩动漫免费观看电视剧高清| 亚洲高清av在线| 亚洲日本中文字幕免费在线不卡| 国产精品午夜一区二区欲梦| 少妇精69xxtheporn| 亚洲一区二区三区xxx视频| 国产精品海角社区在线观看| 欧美成人在线免费视频| 亚洲欧洲日产国产网站| 国产在线视频2019最新视频| 91精品国产91久久久久福利| 国产91ⅴ在线精品免费观看| 国产福利成人在线| 欧美裸体xxxx极品少妇软件| 日本国产欧美一区二区三区| 国内精品久久久久| 精品中文视频在线| 亚洲色图国产精品| 欧美超级乱淫片喷水| 国产欧美一区二区白浆黑人| 色老头一区二区三区| 中文字幕不卡在线视频极品| 日韩在线免费观看视频| 性视频1819p久久| 亚洲精品小视频在线观看| 2019亚洲日韩新视频| 欧美大片大片在线播放| 欧美性生交大片免网| 日韩电影中文字幕在线观看| 久久久久久亚洲精品中文字幕| 精品欧美国产一区二区三区| 久久中文精品视频| 欧美激情在线播放| 中日韩午夜理伦电影免费| 欧美精品中文字幕一区| 91av在线播放| 久久久久久欧美| 成人av资源在线播放| 久久精品视频导航| 国产日韩欧美一二三区| 欧美午夜xxx| 97精品国产97久久久久久| 国产欧美日韩中文字幕| 中文字幕在线视频日韩| 97视频在线观看播放| 久久久久久中文字幕| 午夜精品久久久99热福利| 成人444kkkk在线观看| 久久亚洲精品网站| 2019中文在线观看| 日韩中文字幕在线看| 成人免费直播live| 久久久国产成人精品| yellow中文字幕久久| 亚洲丝袜在线视频| 日韩国产一区三区| 亚洲夜晚福利在线观看| 欧美国产一区二区三区| 国产剧情日韩欧美| 色综合色综合网色综合| 揄拍成人国产精品视频| 国产www精品| 国产日韩欧美中文在线播放| 国产91成人在在线播放| 久久大大胆人体| 亚洲福利视频专区| 欧美人与物videos| 欧美性猛交xxxx乱大交极品| 成人免费淫片视频软件| 国产精品 欧美在线| 久久国产视频网站| 高清视频欧美一级| 97成人超碰免| 国产成人综合av| 久久免费精品日本久久中文字幕| 日韩av一区在线| 91社区国产高清| 亚洲国产精品字幕| 在线电影欧美日韩一区二区私密| 久久综合九色九九| 国产精品高潮视频| 91视频免费在线| 97福利一区二区| 色999日韩欧美国产| 91国内在线视频| 欧美一区二区三区免费视| 欧美韩国理论所午夜片917电影| 欧美午夜片欧美片在线观看| 久久精品99无色码中文字幕| 国产精品扒开腿做爽爽爽男男| 日本不卡免费高清视频| 国产精品亚洲美女av网站| 久久成人在线视频| 中文字幕v亚洲ⅴv天堂| 国产热re99久久6国产精品| 亚洲视频欧美视频| 亚洲精品短视频| 日韩av在线播放资源| 欧美日韩亚洲天堂| 国产日韩欧美电影在线观看| 亚洲精品一二区| 欧美有码在线观看| 亚洲精品美女视频|