最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

Java中的泛型詳解

 更新時(shí)間:2015年04月14日 11:44:01   投稿:junjie  
這篇文章主要介紹了Java中的泛型詳解,本文講解了泛型類或接口、從泛型類派生子類、偽泛型、類型通配符、通配符的上限、通配符的下限、擦除和轉(zhuǎn)換等內(nèi)容,需要的朋友可以參考下

所謂泛型:就是允許在定義類、接口指定類型形參,這個(gè)類型形參在將在聲明變量、創(chuàng)建對象時(shí)確定(即傳入實(shí)際的類型參數(shù),也可稱為類型實(shí)參)

泛型類或接口

“菱形”語法

復(fù)制代碼 代碼如下:

//定義
 
public interface List<E> extends Collection<E> 
 
public class HashMap<K,V> extends AbstractMap<K,V>  implements Map<K,V>, Cloneable, Serializable
//使用
 
List<String> list = new ArrayList();
 
//Java7以后可以省略后面尖括號的類型參數(shù)
 
List<String> list = new ArrayList<>();

從泛型類派生子類

復(fù)制代碼 代碼如下:

//方式1
 
public class App extends GenericType<String>
 
//方式2
 
public class App<T> extends GenericType<T>
 
//方式3
 
public class App extends GenericType

偽泛型

不存在真正的泛型類,泛型類對Java虛擬機(jī)來說是透明的.JVM并不知道泛型類的存在,換句話來說,JVM處理泛型類和普通類沒什么區(qū)別的.因此在靜態(tài)方法、靜態(tài)初始化塊、靜態(tài)變量里面不允許使用類型形參。
- 以下方式都是錯(cuò)誤的

復(fù)制代碼 代碼如下:

private static T data;
 
static{
 
    T f;
 
}
 
public static void func(){
 
    T name = 1;
 
}

下面的例子可以從側(cè)面驗(yàn)證不存在泛型類
復(fù)制代碼 代碼如下:

public static void main(String[] args){
 
        List<String> a1 = new ArrayList<>();
        List<Integer> a2 = new ArrayList<>(); 
    System.out.println(a1.getClass() == a2.getClass());
 
    System.out.println(a1.getClass());
 
    System.out.println(a2.getClass());
 
}

輸出
復(fù)制代碼 代碼如下:

true
 
class java.util.ArrayList
 
class java.util.ArrayList

類型通配符

首先必須明確一點(diǎn),假如Foo是Bar的父類,但是List<Foo>并不是List<Bar>的父類.為了表示各種泛型的父類,Java使用"?"來表示泛型通配.即List<?>來表示各種泛型List的父類.帶這種通配符List泛型不能設(shè)置(set)元素,只能獲?。╣et)元素。因?yàn)槌绦驘o法確定List中的類型,所以不能添加對象。但獲取的對象肯定是Object類型。

以下方法會(huì)編譯出錯(cuò):

復(fù)制代碼 代碼如下:

List<?> list = new ArrayList<>();
 
list.add(new Object());

主意幾點(diǎn):

1.List<String>對象不能被當(dāng)成List<Object>對象使用,也就是說:List<String>類并不是List<Object>類的子類。

2.數(shù)組和泛型有所不同:假設(shè)Foo是Bar的一個(gè)子類型(子類或者子接口),那么Foo[]依然是Bar[]的子類型;但G<Foo>不是G<Bar>的子類型。

3.為了表示各種泛型List的父類,我們需要使用類型通配符,類型通配符是一個(gè)問號(?),將一個(gè)問號作為類型實(shí)參傳給List集合,寫作:List<?>(意思是未知類型元素的List)。這個(gè)問號(?)被稱為通配符,它的元素類型可以匹配任何類型。

通配符的上限

List<? extends SuperType>表示所有SuperType泛型List的父類或本身。帶有通配符上限的泛型不能有set方法,只能有g(shù)et方法。

設(shè)置通配符上限能解決如下問題:Dog是Animal子類,有個(gè)getSize方法要獲取傳入List的個(gè)數(shù),代碼如下

復(fù)制代碼 代碼如下:

abstract class Animal {
    public abstract void run();
}
class Dog extends Animal {
    public void run() {
        System.out.println("Dog run");
    }
}
public class App {
    public static void getSize(List<Animal> list) {
        System.out.println(list.size());
    }
    public static void main(String[] args) {
        List<Dog> list = new ArrayList<>();
        getSize(list); // 這里編譯報(bào)錯(cuò)
    }
}

這里編程出錯(cuò)的原因是List<Animal>并不是List<Dog>的父類。解決方案一可以把getSize方法中形參List<Animal>改為List<?>,不過這樣的話在每次get對象的時(shí)候都要強(qiáng)制類型轉(zhuǎn)換,比較麻煩。使用通配符上限很好的解決了這個(gè)問題,可以把List<Animal>改為List<? extends Animal>,編譯就不會(huì)錯(cuò)了,也不用類型轉(zhuǎn)換。

通配符的下限

List<? super SubType>表示SubType泛型List的下限。帶有通配符上限的泛型不能有g(shù)et方法,只能有set方法。

泛型方法

如果定義類、接口是沒有使用類型形參,但定義方法時(shí)想自己定義類型形參,這也是可以的,JDK1.5還提供了泛型方法的支持。泛型方法的方法簽名比普通方法的方法簽名多了類型形參聲明,類型形參聲明以尖括號括起來,多個(gè)類型形參之間以逗號(,)隔開,所有類型形參聲明放在方法修飾符和方法返回值類型之間.語法格式如下:

復(fù)制代碼 代碼如下:

修飾符 返回值類型 方法名(類形列表){
 
//方法體
 
}

泛型方法允許類型形參被用來表示方法的一個(gè)或多個(gè)參數(shù)之間的類型依賴關(guān)系,或者方法返回值與參數(shù)之間的類型依賴關(guān)系。如果沒有這樣的類型依賴關(guān)系,就不應(yīng)該使用泛型方法。Collections的copy方法就使用泛型方法:
復(fù)制代碼 代碼如下:

 public static <T> void copy(List<? super T> dest, List<? extends T> src){ ...}

這個(gè)方法要求src類型必須是dest類型的子類或本身。

擦除和轉(zhuǎn)換

在嚴(yán)格的泛型代碼里,帶泛型聲明的類總應(yīng)該帶著類型參數(shù)。但為了與老的Java代碼保持一致,也允許在使用帶泛型聲明的類時(shí)不指定類型參數(shù)。如果沒有為這個(gè)泛型類指定類型參數(shù),則該類型參數(shù)被稱作一個(gè)raw type(原始類型),默認(rèn)是該聲明該參數(shù)時(shí)指定的第一個(gè)上限類型。

當(dāng)把一個(gè)具有泛型信息的對象賦給另一個(gè)沒有泛型信息的變量時(shí),則所有在尖括號之間的類型信息都被扔掉了。比如說一個(gè)List<String>類型被轉(zhuǎn)換為List,則該List對集合元素的類型檢查變成了成類型變量的上限(即Object),這種情況被為擦除。

示例

復(fù)制代碼 代碼如下:

class Apple<T extends Number>
 
{
 
 T size;
 
 public Apple()
 
 {
 
 }
 
 public Apple(T size)
 
 {
 
  this.size = size;
 
 }
 
 public void setSize(T size)
 
 {
 
  this.size = size;
 
 }
 
 public T getSize()
 
 {
 
  return this.size;
 
 }
 
}
 
public class ErasureTest
 
{
 
 public static void main(String[] args)
 
 {
 
  Apple<Integer> a = new Apple<>(6);    // ①
 
  // a的getSize方法返回Integer對象
 
  Integer as = a.getSize();
 
  // 把a(bǔ)對象賦給Apple變量,丟失尖括號里的類型信息
 
  Apple b = a;      // ②
 
  // b只知道size的類型是Number
 
  Number size1 = b.getSize();
 
  // 下面代碼引起編譯錯(cuò)誤
 
  Integer size2 = b.getSize();  // ③
 
 }
 
}

相關(guān)文章

  • Java設(shè)計(jì)模式之狀態(tài)模式(State模式)介紹

    Java設(shè)計(jì)模式之狀態(tài)模式(State模式)介紹

    這篇文章主要介紹了Java設(shè)計(jì)模式之狀態(tài)模式(State模式)介紹,本文講解了何時(shí)使用狀態(tài)模式、如何使用狀態(tài)模式等內(nèi)容,需要的朋友可以參考下
    2015-03-03
  • SpringBoot對Druid配置SQL監(jiān)控功能失效問題及解決方法

    SpringBoot對Druid配置SQL監(jiān)控功能失效問題及解決方法

    這篇文章主要介紹了SpringBoot對Druid配置SQL監(jiān)控功能失效問題的解決方法,本文給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2021-05-05
  • java設(shè)計(jì)模式學(xué)習(xí)之代理模式

    java設(shè)計(jì)模式學(xué)習(xí)之代理模式

    這篇文章主要為大家詳細(xì)介紹了java設(shè)計(jì)模式學(xué)習(xí)之代理模式的相關(guān)資料,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2017-10-10
  • Java之SpringBoot-Thymeleaf詳情

    Java之SpringBoot-Thymeleaf詳情

    聊Thymeleaf,需要知道為什么到了SpringBoot中就不用JSP了?這跟SpringBoot打包方式有點(diǎn)關(guān)系,SpringBoot項(xiàng)目打包是jar包,下面文章小編就對此做一個(gè)詳細(xì)介紹,需要的朋友可以參考一下
    2021-09-09
  • java TreeMap源碼解析詳解

    java TreeMap源碼解析詳解

    這篇文章主要介紹了java TreeMap源碼解析詳解的相關(guān)資料,需要的朋友可以參考下
    2017-04-04
  • Kotlin 基礎(chǔ)教程之注解與java中的注解比較

    Kotlin 基礎(chǔ)教程之注解與java中的注解比較

    這篇文章主要介紹了Kotlin 基礎(chǔ)教程之注解與java中的注解比較的相關(guān)資料,需要的朋友可以參考下
    2017-06-06
  • Java 堆內(nèi)存與棧內(nèi)存詳細(xì)介紹

    Java 堆內(nèi)存與棧內(nèi)存詳細(xì)介紹

    這篇文章主要介紹了Java 堆內(nèi)存與棧內(nèi)存詳細(xì)介紹的相關(guān)資料,這里對java 的堆內(nèi)存和棧內(nèi)存進(jìn)行了詳細(xì)的分析,需要的朋友可以參考下
    2016-11-11
  • Java多線程編程中的線程死鎖的問題解決

    Java多線程編程中的線程死鎖的問題解決

    線程死鎖是多線程編程中的一個(gè)常見問題,它發(fā)生在多個(gè)線程互相等待對方釋放資源的情況下,導(dǎo)致程序無法繼續(xù)執(zhí)行,本文就來介紹一下Java多線程編程中的線程死鎖的問題解決,感興趣的可以了解一下
    2023-08-08
  • JAVA 筆記 ClassLoader.getResourceAsStream() 與 Class.getResourceAsStream()的區(qū)別

    JAVA 筆記 ClassLoader.getResourceAsStream() 與 Class.getResourc

    這篇文章主要介紹了JAVA 筆記 ClassLoader.getResourceAsStream() 與 Class.getResourceAsStream()的區(qū)別,本文給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2021-07-07
  • IntellJ IDEA神器使用技巧(小結(jié))

    IntellJ IDEA神器使用技巧(小結(jié))

    這篇文章主要介紹了IntellJ IDEA神器使用技巧(小結(jié)),文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2019-06-06

最新評論

桂阳县| 汉源县| 河源市| 克拉玛依市| 梨树县| 文水县| 德庆县| 舒兰市| 新邵县| 治县。| 杨浦区| 白城市| 禹州市| 泸西县| 得荣县| 台东市| 德钦县| 滁州市| 册亨县| 万山特区| 南木林县| 什邡市| 凤翔县| 贵港市| 巫山县| 阜宁县| 无棣县| 齐河县| 井陉县| 临海市| 玉门市| 固镇县| 东乌珠穆沁旗| 卫辉市| 灵川县| 壤塘县| 五家渠市| 宝兴县| 新丰县| 洪湖市| 武宁县|