国产片侵犯亲女视频播放_亚洲精品二区_在线免费国产视频_欧美精品一区二区三区在线_少妇久久久_在线观看av不卡

服務器之家:專注于服務器技術及軟件下載分享
分類導航

PHP教程|ASP.NET教程|Java教程|ASP教程|編程技術|正則表達式|C/C++|IOS|C#|Swift|Android|JavaScript|易語言|

服務器之家 - 編程語言 - Java教程 - Java泛型定義與用法實例詳解

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

2021-05-28 13:06喜歡特別冷的冬天下著雪 Java教程

這篇文章主要介紹了Java泛型定義與用法,結合實例形式較為詳細的分析了Java中泛型的概念、原理、定義、使用方法及相關操作注意事項,需要的朋友可以參考下

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

1. 泛型的由來

 

先看如下代碼:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
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集合中,然后逐一取出。可以看出,由于list接口在定義時并不知道元素的類型,因此默認為object,即任意類型元素進入list集合后都會自動裝箱。而取值的過程更為復雜,所有取得的值都是裝箱后的object對象,必須得知道每一個元素的初始類型才能拆箱。一般使用集合的時候,集合的元素往往都是具有共同特征的,比如同屬于一類的----那么,如果一開始限定了list集合元素的類型,那么就可避免上述不規范操作。代碼如下,

?
1
2
3
4
5
6
7
8
9
10
11
12
13
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. 泛型類型的繼承關系

 

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

?
1
2
3
4
5
6
7
8
9
10
11
12
13
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 類型通配符

?
1
2
3
4
5
6
7
8
9
10
11
12
13
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 泛型方法

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

?
1
2
3
4
5
6
7
8
9
10
11
12
13
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 泛型方法和通配符的區別

看如下代碼:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
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 泛型參數上、下限的注意

看如下代碼:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
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:

改為

?
1
number lastelement=new testgeneric().copy(des,src);

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

?
1
2
father f=new child();
child c=f;//此處一定報錯,類型不兼容

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

方法2:

改為

?
1
public <t> t copy(collection<? super t> des,collection<t> src)

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

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

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

原文鏈接:https://blog.csdn.net/kkkkkxiaofei/article/details/18262049

延伸 · 閱讀

精彩推薦
Weibo Article 1 Weibo Article 2 Weibo Article 3 Weibo Article 4 Weibo Article 5 Weibo Article 6 Weibo Article 7 Weibo Article 8 Weibo Article 9 Weibo Article 10 Weibo Article 11 Weibo Article 12 Weibo Article 13 Weibo Article 14 Weibo Article 15 Weibo Article 16 Weibo Article 17 Weibo Article 18 Weibo Article 19 Weibo Article 20 Weibo Article 21 Weibo Article 22 Weibo Article 23 Weibo Article 24 Weibo Article 25 Weibo Article 26 Weibo Article 27 Weibo Article 28 Weibo Article 29 Weibo Article 30 Weibo Article 31 Weibo Article 32 Weibo Article 33 Weibo Article 34 Weibo Article 35 Weibo Article 36 Weibo Article 37 Weibo Article 38 Weibo Article 39 Weibo Article 40
主站蜘蛛池模板: 亚洲 中文 欧美 日韩 在线观看 | 超碰一区二区三区 | 国产一区二区三区在线观看免费 | 日韩国产一区 | 免费啪啪av乱一区 | 中文字幕亚洲一区二区三区 | 欧美日韩国产一区 | 国产在线a | 日韩视频在线播放 | 婷婷综合久久 | 人人九九 | 大片免费播放在线观看视频 | 久久久久久久久久久九 | 午夜剧场免费在线观看 | 日韩精品一区二区三区丰满 | 国产精品欧美一区二区三区 | 欧洲一区二区三区 | 欧美成人免费在线视频 | 久久av综合 | 夜夜超碰 | 一区二区三区四区在线播放 | 天天摸天天操 | 中文字幕在线一区二区三区 | 人人澡人人射 | 精品二区| 日本精品在线 | 在线免费观看av电影 | 一区二区三区欧美 | 国产美女网站视频 | 欧美一区二区三区在线观看 | 桃乃木香奈在线 | 午夜视频在线免费看 | 一级做a | 日本在线免费 | 精品在线一区 | 大片免费播放在线观看视频 | 日韩欧美一二三区 | 自拍偷拍小视频 | 亚洲 欧美 日韩在线 | 中文字幕久久精品 | 亚洲免费在线视频 |