java中泛型的理解及使用

1. 泛型的一些概念

Java從1.5開(kāi)始加入了泛型俘陷,主要是解決類(lèi)型安全及擴(kuò)展問(wèn)題,它的本質(zhì)是參數(shù)化類(lèi)型的應(yīng)用观谦,也就是說(shuō)所操作的數(shù)據(jù)類(lèi)型被指定為一個(gè)參數(shù)拉盾。這種參數(shù)類(lèi)型可以用在類(lèi),接口和方法的創(chuàng)建中豁状,分別稱(chēng)為泛型類(lèi)捉偏,泛型接口和泛型方法。

泛型的一些特性:

  • 泛型是類(lèi)型擦除的:Java的泛型只在編譯期有效泻红,它只在程序源碼中存在夭禽,在編譯后的字節(jié)碼文件中就已經(jīng)替換為原來(lái)的原生類(lèi)型。并且在對(duì)象的地方插入了強(qiáng)制轉(zhuǎn)型代碼谊路。因此對(duì)于運(yùn)行期的Java語(yǔ)言來(lái)說(shuō)List<String>和List<Int>就是同一個(gè)類(lèi)讹躯。

  • 泛型識(shí)別:為了解決泛型的識(shí)別問(wèn)題,Java引入了Signature,LocalVaribaleTypeTable等新的屬性用于解決參數(shù)類(lèi)型的識(shí)別問(wèn)題。Signature的作用就是存儲(chǔ)一個(gè)方法在字節(jié)碼層面的特征簽名潮梯,這個(gè)屬性中保存的參數(shù)類(lèi)型并不是原生類(lèi)型骗灶,而是包括了參數(shù)化類(lèi)型的信息。從Signature屬性可以得知秉馏,所謂的擦除僅僅是對(duì)方法的Code屬性中的字節(jié)碼進(jìn)行擦鎖耙旦,實(shí)際上元數(shù)據(jù)中還是保留了泛型信息,所以還是通過(guò)class對(duì)象反射得到泛型信息萝究。

  • 泛型不是協(xié)變的:如String是Object的子類(lèi)免都,但是List<String>并不是List<Object>的子類(lèi)型,它們是2個(gè)單獨(dú)的類(lèi)型帆竹。

2. 泛型的使用

泛型類(lèi)及泛型接口

public class Shop<T> {
    //商品數(shù)量
    int count;
    //抽象商品
    T goods;
    public T get(){
        return t;
    }
}

假如有一個(gè)Shop類(lèi)琴昆,現(xiàn)在并不明確是什么類(lèi)型的店,里面定義了賣(mài)物品的數(shù)量int類(lèi)型的count,以及不確定什么類(lèi)型的商品goods馆揉。

這里有個(gè)問(wèn)題业舍,不確定類(lèi)型,但是必須有類(lèi)型升酣。否則編譯器就會(huì)報(bào)錯(cuò)舷暮。所以要給goods一個(gè)類(lèi)型,因?yàn)椴淮_定噩茄,所以可以先用一個(gè)代號(hào)代替下面,等實(shí)際類(lèi)型確定時(shí)再替換掉,這里使用T绩聘。但是這個(gè)T只是一個(gè)代號(hào)沥割,編譯器不可能認(rèn)識(shí),所以要在類(lèi)名的右邊用<>包裹T凿菩,告訴編譯器T是一個(gè)類(lèi)型的代號(hào)机杜,然后就可以在類(lèi)中使用T代表某種類(lèi)型了。

這里的T不具備特殊意義衅谷,只是到時(shí)會(huì)被替換的實(shí)際類(lèi)型的代號(hào)椒拗,所以它可以隨便寫(xiě)成A,B获黔,C蚀苛,D等等其他任何形式。

再繼續(xù)看玷氏,泛型T可以代表任何類(lèi)型堵未,這個(gè)范圍太廣,如果要限定是某一種類(lèi)型盏触,或符合某些特性呢渗蟹?侦厚,如是一家書(shū)店,所以如果要限定某種類(lèi)型的話就要對(duì)T進(jìn)行限制:

public class Shop<T extends BookShop> {
    
    //商品數(shù)量
    int count;

    //抽象商品
    T goods;

    public T get(){
        return goods;
    }
}

使用extends關(guān)鍵字拙徽,限定了T只能是BookShop類(lèi)型刨沦,那么如果要求即是書(shū)店,又是咖啡店呢:

//如果有2種特性膘怕,直接用&符號(hào)連接,BookShop為類(lèi)想诅,CoffeShop為接口
public class Shop<T extends BookShop & CoffeShop> {

    //商品數(shù)量
    int count;

    //抽象商品
    T goods;

    public T get(){
        return goods;
    }
}

直接使用&符號(hào)連接即可,這里的extends遵循Java的單繼承原則岛心,BookShop和CoffeShop只能一個(gè)是類(lèi)来破,另外個(gè)是接口,當(dāng)然接口是可以多實(shí)現(xiàn)的忘古,繼續(xù)用&連接即可徘禁,如添加Rest屬性:

//如果有2種特性,直接用&符號(hào)連接,BookShop為類(lèi)髓堪,CoffeShop送朱,Rest為接口,遵循Java的單繼承干旁,多實(shí)現(xiàn)原則
public class Shop<T extends BookShop & CoffeShop & Rest> {

    //商品數(shù)量
    int count;

    //抽象商品
    T goods;

    public T get(){
        return goods;
    }
}

再來(lái)看驶沼,假如要開(kāi)一個(gè)分店,BranchShop:

public class BranchShop<B> extends Shop{
    
    int count ;
    
    B goods;

    @Override
    public BookShop get() {
        return super.get();
    }
}

可以看到BranchShop聲明了自己的泛型B(寫(xiě)在類(lèi)右邊争群,用<>包裹)但是重寫(xiě)的get()返回值類(lèi)型變成了BookShop回怜,如果BranchShop需要get()的返回值類(lèi)型是泛型類(lèi)型呢?:

public class BranchShop<B> extends Shop{

    int count ;

    B goods;
        //這里不會(huì)報(bào)錯(cuò)
    public B getGoods(){
        return goods;
    }
    @Override
    //這里會(huì)報(bào)錯(cuò)
    public B get() {
        //這里也會(huì)報(bào)錯(cuò)
        return super.get();
    }
}

getGoods()不會(huì)報(bào)錯(cuò)换薄,但是get()會(huì)報(bào)錯(cuò)玉雾,因?yàn)間et是父Shop的方法,而Shop的泛型T是這樣的:

T extends BookShop & CoffeShop & Rest

它限制了范圍轻要,所以如果要重寫(xiě)父類(lèi)的方法复旬,也要和父類(lèi)的泛型保持一樣的限制(也可以不重寫(xiě),不限制伦腐,如getGoods()):

public class BranchShop<B extends BookShop & CoffeShop & Rest> extends Shop{

    int count ;

    B goods;

    public B getGoods(){
        return goods;
    }
        
    @Override
    //這里不報(bào)錯(cuò)了
    public B get() {
      //這里還是報(bào)錯(cuò)
        return super.get();
    }
}

可以看到當(dāng)B和父類(lèi)的T同步了限制之后赢底,返回值類(lèi)型不報(bào)錯(cuò)了失都,但是super.get()還是報(bào)錯(cuò)柏蘑,這是因?yàn)橹罢f(shuō)過(guò),要使用泛型必須在類(lèi)的右邊聲明粹庞,BranchShop在自己右邊聲明了<B extends BookShop & CoffeShop & Rest>咳焚,但是在BranchShop中,父類(lèi)Shop并沒(méi)有聲明庞溜,沒(méi)有聲明就沒(méi)法使用革半,這里子類(lèi)把父類(lèi)的泛型類(lèi)型丟失了碑定,所以要給它加上聲明:

public class BranchShop<B extends BookShop & CoffeShop & Rest> extends Shop<B>{

    int count ;

    B goods;

    public B getGoods(){
        return goods;
    }

    @Override
    public B get() {
        return super.get();
    }
}

直接在Shop后聲明<B>就OK,這里的泛型就不能隨便寫(xiě)又官,必須和BranchShop的聲明保持一致延刘,也就是必須寫(xiě)成B。

A:public class BranchShop<B extends BookShop & CoffeShop & Rest> extends Shop<B>
B:public class BranchShop<B> extends Shop<B extends BookShop & CoffeShop & Rest>
至于Shop<>,里只能和BranchShop保持一致六敬,以及為什么不寫(xiě)成B碘赖,而寫(xiě)成A這樣,可以簡(jiǎn)單理解為外构,泛型必須聲明在類(lèi)的右邊且必須聲明才能使用普泡。所以Shop<>它是使用泛型,而不是聲明审编,所以不能隨便寫(xiě)成一個(gè)沒(méi)有聲明的類(lèi)型撼班,所以只能是B。所以限制條件也必須加在BranchShop后垒酬,也就是A寫(xiě)法砰嘁。

2. 泛型方法

如果類(lèi)沒(méi)有聲明泛型類(lèi)型,那么如何在方法里使用泛型勘究?般码,看一下一個(gè)常用的方法findViewById():

    public <T extends View> T findViewById(@IdRes int id) {
        return this.getDelegate().findViewById(id);
    }

可以看到,是在返回值前面聲明了T乱顾,并且限制了T extends View,然后返回值就可以使用T了板祝。

3. 通配符

  • 上界通配符
public class FruitShop {
        //Apple集合,Apple繼承自Fruit
    List<Apple> apples;
      //Orange集合走净,Orange繼承自Fruit
    List<Orange> oranges;
        //這樣寫(xiě)沒(méi)法遍歷Apple和Orange集合
    public  void getFruit(List<Fruit> fruits){
    }
}

假如有一個(gè)水果店券时,需要一個(gè)通用的方法遍歷每一種水果,但是由于泛型不是協(xié)變的伏伯,所以上面的getFruit()是沒(méi)法遍歷Apple和Orange集合的橘洞,這里要解決這個(gè)問(wèn)題,要用到? extends關(guān)鍵字:

public class FruitShop {

    List<Apple> apples;

    List<Orange> oranges;

    public  void getFruit(List<? extends Fruit> fruits){
        for (int i = 0; i < fruits.size(); i++) {
            //得到每一個(gè)fruit
            Fruit fruit = fruits.get(i);
        }

    }
}

使用? extends Fruit代表了Fruit某個(gè)字類(lèi)型说搅,所以只要是Fruit子類(lèi)型都可以(每個(gè)類(lèi)型都是自身的子類(lèi)型)進(jìn)行遍歷炸枣。

但是上界通配符有一個(gè)問(wèn)題:

public class FruitShop<E> {

    List<Apple> apples;

    List<Orange> oranges;

    public  void getFruit(List<? extends Fruit> fruits){
        //不報(bào)錯(cuò)
        fruits.get(0);
            //這里報(bào)錯(cuò)
        fruits.add(new Orange());
    }
}

在getFruit()接收了一個(gè)Fruit一個(gè)子類(lèi)型的List,但是只知道是Fruit的子類(lèi)型弄唧,具體是哪種子類(lèi)型是不知道的适肠,如上圖,很可能傳入了一個(gè)Apple的的List候引,但是有可能添加進(jìn)一個(gè)Orange侯养,所以Java不允許這樣操作。

這就是上界通配符澄干?extends T,限制了逛揩?只能是T或者T的子類(lèi)柠傍,并且只能取內(nèi)容,不能存內(nèi)容

  • 下界通配符
    public void setFruit(List<? super Fruit> fruits){
        fruits.add(new Apple());
        Object object = fruits.get(0);
    }

和上界通配符剛好相反辩稽,下屆通配符代表可以接受Fruit及它的所有超類(lèi)型惧笛。
它的特性是可以存東西,但是不能取逞泄,或者只能用Object接收徐紧,但是類(lèi)型信息會(huì)全部丟失。因?yàn)榇_定取的到底是什么類(lèi)型炭懊。

  • 無(wú)界通配符
    //無(wú)界通配符
    public void setFruit(List<?> fruits){
        //這行報(bào)錯(cuò)
        fruits.add(new Apple());
        //同樣只能用Object接收
        Object o = fruits.get(0);
    } 

并级?代表不進(jìn)行任何限制,可以是任何類(lèi)型侮腹。所以它既不能存嘲碧,也不能取(或者取出的值元素只能用Object接收)父阻。

但是可以通過(guò)寫(xiě)一個(gè)幫助類(lèi)愈涩,來(lái)達(dá)到讓?zhuān)磕苋〉墓δ埽?/p>

    public void setFruit(List<?> fruits){
        //這行報(bào)錯(cuò)
        fruits.add(fruits.get(0));
        //只能獲取到Object類(lèi)型
        Object o = fruits.get(0);
        setFruitHelper(fruits);
    }

    public <E> void setFruitHelper(List<E> e){
        //這行不報(bào)錯(cuò)
        e.add(e.get(0));
        //可以獲取到T類(lèi)型
        T t = e.get(0);


    }

setFruitHelper()知道e列表中取出的任何值均為E類(lèi)型,并且知道E類(lèi)型的任何值放進(jìn)列表都是安全的加矛。

無(wú)界通配符也有要注意的問(wèn)題:

    public  void test(){
    //構(gòu)造一個(gè)下界通配符集合
    List<? super Fruit> f =new ArrayList<>();
     //添加Apple
     f.add(new Apple());
     //添加Orange
     f.add(new Orange());
      //把下屆通配符集合傳入無(wú)界通配符集合里
      setFruit(f);
    }
    
    public void setFruit(List<?> fruits){
        //調(diào)用Helper方法
        setFruitHelper(fruits);
    }

    public <T> void setFruitHelper(List<T> e){
        //在這里執(zhí)行g(shù)et()以及add()
      
        //取出的是Apple
        T t = e.get(0);
        //添加的是Apple
        e.add(e.get(0));
        //取出的是Orange
        T t = e.get(1);
        //添加的是Orange
        e.add(e.get(1));

    }

可以看到通過(guò)setFruitHelper()履婉,規(guī)避了下界通配符不能取的問(wèn)題。使用的時(shí)候需要注意斟览。

3. 獲取泛型類(lèi)型

前面說(shuō)過(guò)毁腿,泛型在運(yùn)行期間是擦除的,但是會(huì)保存在class文件里苛茂,所以可以從class里獲取

1. 獲取類(lèi)及接口泛型已烤,Java提供了2個(gè)關(guān)于泛型的方法:

  • getGenericSuperclass:返回此類(lèi)所表示的實(shí)體的直接超類(lèi)的類(lèi)型,看一下代碼
//part1:AppleShop自身的泛型T妓羊,明確了父類(lèi)FruitShop的泛型Apple
public class AppleShop<T> extends FruitShop<Apple> {

}

//part 2
//獲取AppleShop的class
Class<AppleShop> appleShopClass = AppleShop.class;
//獲取type
Type genericSuperclass = appleShopClass.getGenericSuperclass();
//獲取具體type的數(shù)組結(jié)合
Type[] actualTypeArguments = ((ParameterizedType)genericSuperclass).getActualTypeArguments();


可以看到在part1中胯究,AppleShop類(lèi)聲明了自身的泛型T,明確了父類(lèi)的泛型類(lèi)型為Apple

然后在part2中躁绸,先獲取了AppleShop的class裕循,class通過(guò)調(diào)用getGenericSuperclass(),返回了Type净刮。

然后通過(guò)type再獲取具體的泛型數(shù)組剥哑,由于這里只有一個(gè)泛型,所以取第一個(gè)actualTypeArguments[0],分別看一下它們的結(jié)果:

type:xxx.xxx.xxx.FruitShop<xxx.xxx.xxx.Apple>
actualTypeArguments[0]:xxx.xxx.xxx.Apple

可以看到type包含了父類(lèi)FruitShop信息庭瑰,actualTypeArguments[0]返回了具體泛型類(lèi)型星持。

這里要注意一點(diǎn),這個(gè)方法獲取的是明確的父類(lèi)泛型弹灭,不是自身聲明的泛型類(lèi)型榕暇。因?yàn)樽陨矸盒皖?lèi)型這時(shí)還并沒(méi)有確定饱须。

  • getGenericInterfaces:返回此類(lèi)直接實(shí)現(xiàn)的所有接口類(lèi)型,看一下代碼:
//part1:明確了父類(lèi)FruitShop的泛型Apple
public class AppleShop implements Rest<Apple> {

}
//part2:
//獲取AppleShop的class
Class<AppleShop> appleShopClass = AppleShop.class;
//獲取type數(shù)組(因?yàn)榭赡軐?shí)現(xiàn)多個(gè)接口,所以是數(shù)組)
Type[] genericInterfaces = appleShopClass.getGenericInterfaces();
//取第一個(gè)的type
ParameterizedType genericInterface = (ParameterizedType) genericInterfaces[0];
//獲取具體type的數(shù)組結(jié)合
Type[] actualTypeArguments = genericInterface.getActualTypeArguments();

看一下獲取結(jié)果:

type:xxx.xxx.xxx.FruitShop<xxx.xxx.xxx.Apple>
actualTypeArguments[0]:xxx.xxx.xxx.Apple

和getGenericSuperclass的過(guò)程和結(jié)果都是一樣的奈惑。

2. 獲取方法和成員變量的泛型

方法及成員變量的泛型,可以通過(guò)反射獲取拐叉。

public class AppleShop<T> extends FruitShop<Apple> {
        //成員變量泛型
    List<Apple> apples = new ArrayList<>();
        //方法泛型毫深,包括返回值泛型以及參數(shù)泛型
    public List<Apple> getApples(List<Apple> count){
       
        return apples;
    }

}

看一下如何獲取的代碼:

//獲取class
        Class<AppleShop> appleShopClass = AppleShop.class;
        try {
            //獲取apples成員變量,這里只是測(cè)試驾诈,使用了獲取單個(gè)成員變量的方法
            Field apples = appleShopClass.getDeclaredField("apples");
            //獲取成員變量的type
            Type genericType = apples.getGenericType();
            //獲取成員變量泛型的具體type
            Type[] actualTypeArguments = ((ParameterizedType) genericType).getActualTypeArguments();

        }catch (Exception e){

        }

        try{
            //獲取getApples(),這里只是測(cè)試缠诅,使用了獲取單個(gè)方法的方法
            Method getApples = appleShopClass.getMethod("getApples", new Class[]{List.class});
            //獲取方法參數(shù)的Type集合
            Type[] genericParameterTypes = getApples.getGenericParameterTypes();
            //取第一個(gè)參數(shù)的具體Type
            ParameterizedType genericParameterType = (ParameterizedType) genericParameterTypes[0];
            //取第一個(gè)參數(shù)的具體類(lèi)型集合
            Type[] actualTypeArguments1 = genericParameterType.getActualTypeArguments();
            
            //獲取getApples()的返回值Type
            Type genericReturnType = getApples.getGenericReturnType();
            //獲取返回值具體類(lèi)型的Type集合
            Type[] actualTypeArguments = ((ParameterizedType) genericReturnType).getActualTypeArguments();

        }catch (Exception e){

        }


以上就是獲取成員變量以及方法返回值,方法參數(shù)泛型類(lèi)型的方式乍迄。

3. 運(yùn)行時(shí)代碼的泛型

前面的都是通過(guò)class獲取的泛型類(lèi)型管引,但是有些代碼是運(yùn)行時(shí)才確定的,如下:

    public List<Apple> getApples(List<Apple> count){
            //這里運(yùn)行時(shí)才會(huì)確定
        List <Orange> oranges=new ArrayList<>();
        return apples;
    }

運(yùn)行時(shí)才能確定的闯两,通過(guò)之前的方法就沒(méi)法獲取褥伴。

還是前面說(shuō)過(guò),class會(huì)保留泛型信息,那么這里通過(guò)建立匿名內(nèi)部類(lèi)的方式漾狼,然后就會(huì)產(chǎn)生class文件重慢,從而讓泛型類(lèi)型保存起來(lái),如下:

  public List<Apple> getApples(List<Apple> count){
            //通過(guò)在后面加一個(gè){}的方式建立一個(gè)匿名內(nèi)部類(lèi)
        List <Apple> applesList=new ArrayList<Apple>(){};
            //獲取type,和之前一樣
        Type genericSuperclass = applesList.getClass().getGenericSuperclass();
        return apples;
    }

通過(guò)建立一個(gè)匿名內(nèi)部類(lèi)的方式逊躁,產(chǎn)生class文件似踱,然后就可以獲取泛型類(lèi)型了。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末稽煤,一起剝皮案震驚了整個(gè)濱河市屯援,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌念脯,老刑警劉巖狞洋,帶你破解...
    沈念sama閱讀 212,686評(píng)論 6 492
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異绿店,居然都是意外死亡吉懊,警方通過(guò)查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,668評(píng)論 3 385
  • 文/潘曉璐 我一進(jìn)店門(mén)假勿,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)借嗽,“玉大人,你說(shuō)我怎么就攤上這事转培《竦迹” “怎么了?”我有些...
    開(kāi)封第一講書(shū)人閱讀 158,160評(píng)論 0 348
  • 文/不壞的土叔 我叫張陵浸须,是天一觀的道長(zhǎng)惨寿。 經(jīng)常有香客問(wèn)我邦泄,道長(zhǎng),這世上最難降的妖魔是什么裂垦? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 56,736評(píng)論 1 284
  • 正文 為了忘掉前任顺囊,我火速辦了婚禮,結(jié)果婚禮上蕉拢,老公的妹妹穿的比我還像新娘特碳。我一直安慰自己,他們只是感情好晕换,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,847評(píng)論 6 386
  • 文/花漫 我一把揭開(kāi)白布午乓。 她就那樣靜靜地躺著,像睡著了一般闸准。 火紅的嫁衣襯著肌膚如雪益愈。 梳的紋絲不亂的頭發(fā)上,一...
    開(kāi)封第一講書(shū)人閱讀 50,043評(píng)論 1 291
  • 那天恕汇,我揣著相機(jī)與錄音腕唧,去河邊找鬼。 笑死瘾英,一個(gè)胖子當(dāng)著我的面吹牛枣接,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播缺谴,決...
    沈念sama閱讀 39,129評(píng)論 3 410
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼但惶,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來(lái)了湿蛔?” 一聲冷哼從身側(cè)響起膀曾,我...
    開(kāi)封第一講書(shū)人閱讀 37,872評(píng)論 0 268
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎阳啥,沒(méi)想到半個(gè)月后添谊,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 44,318評(píng)論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡察迟,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,645評(píng)論 2 327
  • 正文 我和宋清朗相戀三年斩狱,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片扎瓶。...
    茶點(diǎn)故事閱讀 38,777評(píng)論 1 341
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡所踊,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出概荷,到底是詐尸還是另有隱情秕岛,我是刑警寧澤,帶...
    沈念sama閱讀 34,470評(píng)論 4 333
  • 正文 年R本政府宣布,位于F島的核電站继薛,受9級(jí)特大地震影響修壕,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜惋增,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 40,126評(píng)論 3 317
  • 文/蒙蒙 一叠殷、第九天 我趴在偏房一處隱蔽的房頂上張望改鲫。 院中可真熱鬧诈皿,春花似錦、人聲如沸像棘。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 30,861評(píng)論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)缕题。三九已至截歉,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間烟零,已是汗流浹背瘪松。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 32,095評(píng)論 1 267
  • 我被黑心中介騙來(lái)泰國(guó)打工, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留锨阿,地道東北人宵睦。 一個(gè)月前我還...
    沈念sama閱讀 46,589評(píng)論 2 362
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像墅诡,于是被迫代替她去往敵國(guó)和親壳嚎。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,687評(píng)論 2 351

推薦閱讀更多精彩內(nèi)容

  • 前言 泛型(Generics)的型變是Java中比較難以理解和使用的部分,“神秘”的通配符然磷,讓我看了幾遍《Java...
    珞澤珈群閱讀 7,807評(píng)論 12 51
  • 參數(shù)類(lèi)型的好處 在 Java 引入泛型之前郑趁,泛型程序設(shè)計(jì)是用繼承實(shí)現(xiàn)的。ArrayList 類(lèi)只維護(hù)一個(gè) Obje...
    杰哥長(zhǎng)得帥閱讀 872評(píng)論 0 3
  • ArrayList就是個(gè)泛型類(lèi)姿搜,我們通過(guò)設(shè)定不同的類(lèi)型寡润,可以往集合里面存儲(chǔ)不同類(lèi)型的數(shù)據(jù)類(lèi)型(而且只能存儲(chǔ)設(shè)定的數(shù)...
    dinel閱讀 481評(píng)論 0 2
  • 1.泛型簡(jiǎn)介 問(wèn)題:在獲取用戶(hù)信息的API中,后臺(tái)給我們返回一個(gè)這樣形式的json字符串痪欲。{ "meta":...
    彼岸之城cyy閱讀 955評(píng)論 0 0
  • 簡(jiǎn)介 泛型的意思就是參數(shù)化類(lèi)型悦穿,通過(guò)使用參數(shù)化類(lèi)型創(chuàng)建的接口、類(lèi)业踢、方法栗柒,可以指定所操作的數(shù)據(jù)類(lèi)型。比如:可以使用參...
    零度沸騰_yjz閱讀 3,308評(píng)論 1 15