java 泛型特性

泛型

  1. oracle原文地址:https://docs.oracle.com/javase/tutorial/java/generics/erasure.html
    在Java中静秆,泛型的引入是為了在編譯時提供強類型檢查和支持泛型編程竣况。為了實現(xiàn)泛型区赵,Java編譯器應用類型擦除實現(xiàn):
    1受楼、 用類型參數(shù)(type parameters)的限定(如果沒有就用Object)替換泛型類型中的所有類型參數(shù)虏冻。
    2贬墩、 需要保持類型安全的時候插入類型轉(zhuǎn)換(隱含插入)
    3呀闻、 在extened 泛型類型中生成橋方法來保證多態(tài)性
    類型擦除確保不會為已參數(shù)化了的類型(paramterized types)產(chǎn)生新類精肃,這樣泛型能保證沒有運行時的負載秤涩。

  2. 泛型的好處是在編譯的時候檢查類型安全,減少運行時的問題司抱;避免強制轉(zhuǎn)換的麻煩筐眷;

特性

只在編譯階段有效。在編譯過程中习柠,正確檢驗泛型結(jié)果后匀谣,會將泛型的相關(guān)信息擦除
如:

public class MyClass {

    private static List<String> list1 = new ArrayList<>();
    private static List<Integer> list2 = new ArrayList<>();


    public static void main(String args[]){
        list1.add("aaaa");
        list2.add(11);
        System.out.println("----list1------>" + list1.getClass());
        System.out.println("----list2------>" + list2.getClass());
        System.out.println("泛型類型是否相同-->" + list2.getClass().equals(list1.getClass()));
    }
}

輸出結(jié)果:

----list1------>class java.util.ArrayList
----list2------>class java.util.ArrayList
泛型類型是否相同-->true

在編譯之后程序會采取去泛型化的措施照棋。也就是說Java中的泛型,只在編譯階段有效武翎。在編譯過程中必怜,正確檢驗泛型結(jié)果后,會將泛型的相關(guān)信息擦出后频,并且在對象進入和離開方法的邊界處添加類型檢查和類型轉(zhuǎn)換的方法梳庆。也就是說,泛型信息不會進入到運行時階段卑惜。

對此總結(jié)成一句話:泛型類型在邏輯上看以看成是多個不同的類型膏执,實際上都是相同的基本類型。

擦除規(guī)則

JVM并不知道泛型的存在露久,因為泛型在編譯階段就已經(jīng)被處理成普通的類和方法更米;
處理機制是通過類型擦除,擦除規(guī)則:

若泛型類型沒有指定具體類型毫痕,用Object作為原始類型征峦;
若有限定類型< T exnteds XClass >,使用XClass作為原始類型消请;
若有多個限定< T exnteds XClass1 & XClass2 >栏笆,使用第一個邊界類型XClass1 XClass2作為原始類型
如下例:
測試目錄結(jié)構(gòu)
├── MyClass.java //測試類
├── parent
│ ├── IOne.java //接口1
│ ├── ITwo.java //接口2
│ └── ParentOne.java //父類
├── sun
│ ├── Sun.java
│ └── SunOne.java
├── Test.java
├── TestOne.java
└── TestTwo.java

定義測試類

package com.example.test;

import com.example.test.sun.Sun;
import com.example.test.sun.SunOne;

public class MyClass {
    public static void main(String args[]){
        //無限定
        Test test = new Test();
        test.setT("test");
        //< T exnteds XClass > 限定
        TestOne testOne = new TestOne();
        testOne.setT(new SunOne());
        //多個限定< T exnteds XClass1 & XClass2 >
        TestTwo testTwo = new TestTwo();
        testTwo.setT(new Sun());
        System.out.println("----test------>" + test.getClass());
        System.out.println("----testOne------>" + testOne.getClass());
        System.out.println("----testTwo------>" + testTwo.getClass());
    }

}

無限定

package com.example.test;

/**
 * T 無限定
 * @param <T>
 */
public class Test<T> {
    /**
     * T 最終等同于
     *   private Object t;
     */
    private T t;

    public void setT(T t) {
        this.t = t;
    }
}

單個限定

package com.example.test;

import com.example.test.parent.ParentOne;

/**
 * T 傳入的類型必須繼承于ParentOne
 * @param <T>
 */
public class TestOne<T extends ParentOne> {

    private T t;

    public void setT(T t) {
        this.t = t;
    }
}


package com.example.test.sun;

import com.example.test.parent.ParentOne;

public class SunOne extends ParentOne {
}

package com.example.test.parent;

public class ParentOne {
}

多個限定 類實現(xiàn)兩個接口

package com.example.test;

import com.example.test.parent.IOne;
import com.example.test.parent.ITwo;

/**
 * T 類型 必須繼承IOne ITwo 接口
 * @param <T>
 */
public class TestTwo<T extends IOne & ITwo> {
    private T t;

    public void setT(T t) {
        this.t = t;
    }
}

package com.example.test.sun;

import com.example.test.parent.IOne;
import com.example.test.parent.ITwo;

public class Sun implements IOne,ITwo {
}

package com.example.test.parent;

public interface ITwo {
}

package com.example.test.parent;

public interface IOne {
}

泛型中占位符T和?區(qū)別

“<T>"和"<?>",首先要區(qū)分開兩種不同的場景:

  1. 第一臊泰,聲明一個泛型類或泛型方法蛉加。
  2. 第二,使用泛型類或泛型方法缸逃。
  3. 類型參數(shù)“<T>”主要用于第一種针饥,聲明泛型類或泛型方法。
  4. 無界通配符“<?>”主要用于第二種需频,使用泛型類或泛型方法
    泛型的限定:
    ? extends E:接收E類型或者E的子類型丁眼。
    ?super E:接收E類型或者E的父類型昭殉。
    簡單例子
package com.example.test;

import java.util.ArrayList;
import java.util.List;

public class MyClass {
    private static List list1 = new ArrayList();
    private static List<String> list2 = new ArrayList();
    public static void main(String args[]){
        list1.add("aaa");
        list1.add(33);
        list2.add("bbbb");
        list2.add("cccc");
        for (int i =0 ;i<list1.size();i++){
            System.out.println("---------->" + list1.get(i));
        }
        System.out.println("-----#############-----");
        for (int i =0 ;i<list2.size();i++){
            System.out.println("---------->" + list2.get(i));
        }
    }
}

輸出

---------->aaa
---------->33
-----#############-----
---------->bbbb
---------->cccc

一個限定類型苞七,只能add String
另一個,可添加多種類型的數(shù)據(jù)

//使用通配符饲化?
SuperClass<?> sup = new SuperClass<String>("例子");
sup = new SuperClass<Student>(new Student());
sup = new SuperClass<Teacher>(new Teacher());
//不使用通配符
SuperClass<String> sup1 = new SuperClass<String>("lisi");
SuperClass<Student> sup2 = new SuperClass<Student>(new Student());
SuperClass<Teacher> sup3 = new SuperClass<Teacher>(new Teacher());
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末莽鸭,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子吃靠,更是在濱河造成了極大的恐慌,老刑警劉巖足淆,帶你破解...
    沈念sama閱讀 212,454評論 6 493
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件巢块,死亡現(xiàn)場離奇詭異礁阁,居然都是意外死亡,警方通過查閱死者的電腦和手機族奢,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,553評論 3 385
  • 文/潘曉璐 我一進店門姥闭,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人越走,你說我怎么就攤上這事棚品。” “怎么了廊敌?”我有些...
    開封第一講書人閱讀 157,921評論 0 348
  • 文/不壞的土叔 我叫張陵铜跑,是天一觀的道長。 經(jīng)常有香客問我骡澈,道長锅纺,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 56,648評論 1 284
  • 正文 為了忘掉前任肋殴,我火速辦了婚禮囤锉,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘护锤。我一直安慰自己官地,他們只是感情好,可當我...
    茶點故事閱讀 65,770評論 6 386
  • 文/花漫 我一把揭開白布烙懦。 她就那樣靜靜地躺著区丑,像睡著了一般。 火紅的嫁衣襯著肌膚如雪修陡。 梳的紋絲不亂的頭發(fā)上沧侥,一...
    開封第一講書人閱讀 49,950評論 1 291
  • 那天,我揣著相機與錄音魄鸦,去河邊找鬼宴杀。 笑死,一個胖子當著我的面吹牛拾因,可吹牛的內(nèi)容都是我干的旺罢。 我是一名探鬼主播,決...
    沈念sama閱讀 39,090評論 3 410
  • 文/蒼蘭香墨 我猛地睜開眼绢记,長吁一口氣:“原來是場噩夢啊……” “哼扁达!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起蠢熄,我...
    開封第一講書人閱讀 37,817評論 0 268
  • 序言:老撾萬榮一對情侶失蹤跪解,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后签孔,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體叉讥,經(jīng)...
    沈念sama閱讀 44,275評論 1 303
  • 正文 獨居荒郊野嶺守林人離奇死亡窘行,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 36,592評論 2 327
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了图仓。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片罐盔。...
    茶點故事閱讀 38,724評論 1 341
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖救崔,靈堂內(nèi)的尸體忽然破棺而出惶看,到底是詐尸還是另有隱情,我是刑警寧澤六孵,帶...
    沈念sama閱讀 34,409評論 4 333
  • 正文 年R本政府宣布纬黎,位于F島的核電站,受9級特大地震影響狸臣,放射性物質(zhì)發(fā)生泄漏莹桅。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 40,052評論 3 316
  • 文/蒙蒙 一烛亦、第九天 我趴在偏房一處隱蔽的房頂上張望诈泼。 院中可真熱鬧,春花似錦煤禽、人聲如沸铐达。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,815評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽瓮孙。三九已至,卻和暖如春选脊,著一層夾襖步出監(jiān)牢的瞬間杭抠,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 32,043評論 1 266
  • 我被黑心中介騙來泰國打工恳啥, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留偏灿,地道東北人。 一個月前我還...
    沈念sama閱讀 46,503評論 2 361
  • 正文 我出身青樓钝的,卻偏偏與公主長得像翁垂,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子硝桩,可洞房花燭夜當晚...
    茶點故事閱讀 43,627評論 2 350