日韩av黄I国产麻豆传媒I国产91av视频在线观看I日韩一区二区三区在线看I美女国产在线I麻豆视频国产在线观看I成人黄色短片

歡迎訪問(wèn) 生活随笔!

生活随笔

當(dāng)前位置: 首頁(yè) >

[转载] 详解Java中的泛型

發(fā)布時(shí)間:2025/3/11 22 豆豆
生活随笔 收集整理的這篇文章主要介紹了 [转载] 详解Java中的泛型 小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

參考鏈接: Java中具有泛型的有界類型

1、什么是泛型?

?

泛型,即“參數(shù)化類型”。一提到參數(shù),最熟悉的就是定義方法時(shí)有形參,然后調(diào)用此方法時(shí)傳遞實(shí)參。那么參數(shù)化類型怎么理解呢?顧名思義,就是將類型由原來(lái)的具體的類型參數(shù)化,類似于方法中的變量參數(shù),此時(shí)類型也定義成參數(shù)形式(可以稱之為類型形參),然后在使用/調(diào)用時(shí)傳入具體的類型(類型實(shí)參)。?

2、一個(gè)小例子?

?

import java.util.ArrayList;

import java.util.List;

?

public static void main(String[] args) {

?

? ? ? ? List list = new ArrayList();

? ? ? ? list.add("hello");

? ? ? ? list.add("hallo");

? ? ? ? list.add(1);

? ? ? ? for (int i = 0; i < list.size(); i++) {

? ? ? ? ? ? String str = (String) list.get(i);

? ? ? ? ? ? System.out.println(str);

? ? ? ? }

? ? }

}?

上面的程序:? 編譯階段正常,而運(yùn)行時(shí)會(huì)出現(xiàn)異常?

Exception in thread "main" java.lang.ClassCastException: java.lang.Integer cannot be cast to java.lang.String?

存在的問(wèn)題:? 當(dāng)把一個(gè)對(duì)象收入集合中,集合不會(huì)記住此對(duì)象的類型,當(dāng)再次從集合中取出此對(duì)象時(shí),對(duì)象變成了Object類型,但其運(yùn)行時(shí)類型任然為其本身類型。強(qiáng)制轉(zhuǎn)換時(shí),容易出現(xiàn)異常,正如程序中把Integer轉(zhuǎn)為String失敗。?

解決方法:? 通過(guò)使用泛型來(lái)使集合能夠記住集合內(nèi)元素各類型?

將上面的代碼用泛型來(lái)實(shí)現(xiàn)?

import java.util.ArrayList;

import java.util.List;

?

public class Main {

? ? public static void main(String[] args) {

? ? ? ? List<String> list = new ArrayList<String>();

? ? ? ? list.add("hello");

? ? ? ? list.add("hallo");

? ? ? ? list.add(1);

? ? ? ? for (int i = 0; i < list.size(); i++) {

? ? ? ? ? ? String str = list.get(i);

? ? ? ? ? ? System.out.println(str);

? ? ? ? }

? ? }

}?

這時(shí),編譯錯(cuò)誤,無(wú)法運(yùn)行?

Error:(13, 13) java: 對(duì)于add(int), 找不到合適的方法

? ? 方法 java.util.Collection.add(java.lang.String)不適用

? ? ? (參數(shù)不匹配; int無(wú)法轉(zhuǎn)換為java.lang.String)

? ? 方法 java.util.List.add(java.lang.String)不適用

? ? ? (參數(shù)不匹配; int無(wú)法轉(zhuǎn)換為java.lang.String)?

通過(guò)List,直接限定了list集合中只能含有String類型的元素,從而在取得集合中的元素時(shí)無(wú)須進(jìn)行強(qiáng)制類型轉(zhuǎn)換,編譯器可以確定集合中存的都是String類型。?

3、泛型的特性?

?

Java中的泛型,只在編譯階段有效。?

在編譯過(guò)程中,正確檢驗(yàn)泛型結(jié)果后,會(huì)將泛型的相關(guān)信息擦出,并且在對(duì)象進(jìn)入和離開(kāi)方法的邊界處添加類型檢查和類型轉(zhuǎn)換的方法。?

泛型信息不會(huì)進(jìn)入到運(yùn)行時(shí)階段。?

4、泛型的使用?

?

在泛型使用過(guò)程中,操作的數(shù)據(jù)類型被指定為一個(gè)參數(shù),這種參數(shù)類型可以用在類、接口和方法中,分別被稱為泛型類、泛型接口、泛型方法。?

以幾個(gè)小例子來(lái)分析一下?

(1) 泛型類?

public class ArrayList<E>

extends AbstractList<E>

implements List<E>, RandomAccess, Cloneable, Serializable?

用泛型類聲明與建立對(duì)象?

ArrayList<String> list = new ArrayList<String>();?

JDK7之后可以寫(xiě)成:?

ArrayList<String> list = new ArrayList<>();?

(2) 泛型接口?

...

public interface Comparator<T>{

? ? int compare(T o1, T o2);

? ? ...

}?

使用方法?

public class StringComparator implements Comparator<String>{

? ? @Override

? ? public int compare(String s1, String s2){

? ? ? ? return -s1.compareTo(s2);

? ? }

}?

(3) 泛型方法?

public static <T> T elemof(T[] objs,int index){

? ? return objs[index];

}?

使用方法?

public static String elemof(String[] objs,int index){

? ? return objs[index];

}?

5、泛型的上下邊界問(wèn)題?

?

可以使用extends與super關(guān)鍵字、?類型通配符來(lái)限制泛型,并且可以結(jié)合這三者來(lái)模擬共變性與逆變性。?

共變性與逆變性?

如果B是A的子類,而Node< B >可視為一種Node< A >,則稱Node具有共變性(Covariance)或者有彈性的(Flexible)。?

如果B是A的子類,而Node< A >可視為一種Node< B >,則稱Node具有逆變性(Contravariance)。?

Java泛型不支持共變性與逆變性?

(1) 使用?與extends來(lái)模擬共變性?

class Fruit{}

class Apple extends Fruit{}

class RedApple extends Apple{}

?

List< ? extends Fruit > list1 = new ArrayList<Fruit>();

List< ? extends Fruit > list2 = new ArrayList<Apple>();

List< ? extends Fruit > list3 = new ArrayList<RedApple>();?

Fruit為上界,即List< ? extends Fruit >類型的對(duì)象可以引用持有Fruit及其子類的容器。?

關(guān)于一個(gè)add方法:?

void add(List< ? extends Fruit > list, Apple a){

? ? ?list.add(a);

}?

如果list引用的是持有RedApple類型的容器,那么將Apple類型向下轉(zhuǎn)型是不安全的,所以用List< ? extends Fruit >,add方法是受到限制的,即無(wú)法向容器中添加任何實(shí)際的類型除了null。?

(2) 使用?與super來(lái)模擬逆變性?

List< ? super RedApple > list4 = new ArrayList<RedApple>();

List< ? super RedApple > list5 = new ArrayList<Apple>();?

RedApple為下界,即List< ? super RedApple >類型的對(duì)象可以引用持有RedApple及其父類的容器。?

此時(shí)add方法是沒(méi)有限制的,但是也只能是添加Jonathan及其父類型。若事先不知道List< ? super RedApple >引用的對(duì)象所持有的類型,則可以做到向上轉(zhuǎn)型,而向上轉(zhuǎn)型是安全的。?

6、小結(jié)?

?

泛型的本質(zhì)是:參數(shù)化類型?

只在編譯階段有效,泛型使用無(wú)錯(cuò)誤時(shí),擦出泛型的相關(guān)信息,并且在對(duì)象進(jìn)入和離開(kāi)方法的邊界處添加類型檢查和類型轉(zhuǎn)換的方法,泛型信息不會(huì)進(jìn)入到運(yùn)行時(shí)階段。?

泛型可以被用在類、接口和方法中,而且可以限制泛型的上下界。?

雖然Java泛型不支持共變性與逆變性,但是?與extends可模擬共變性;?與super可模擬逆變性。?

?

參考資料?

《Java學(xué)習(xí)筆記》 林信良?

Java泛型的邊界問(wèn)題?

java 泛型詳解-絕對(duì)是對(duì)泛型方法講解最詳細(xì)的,沒(méi)有之一

總結(jié)

以上是生活随笔為你收集整理的[转载] 详解Java中的泛型的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。

如果覺(jué)得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。