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

一篇文章帶你搞定JAVA泛型

 更新時(shí)間:2021年07月14日 10:01:20   作者:香菜聊游戲  
泛型是Java中的高級(jí)概念,也是構(gòu)建框架必備技能,比如各種集合類都是泛型實(shí)現(xiàn)的,今天詳細(xì)聊聊Java中的泛型概念,希望有所收獲

1、泛型的概念

泛型的作用就是把類型參數(shù)化,也就是我們常說(shuō)的類型參數(shù)

平時(shí)我們接觸的普通方法的參數(shù),比如public void fun(String s);參數(shù)的類型是String,是固定的

現(xiàn)在泛型的作用就是再將String定義為可變的參數(shù),即定義一個(gè)類型參數(shù)T,比如public static <T> void fun(T t);這時(shí)參數(shù)的類型就是T的類型,是不固定的

泛型常見(jiàn)的字母有以下:

? 表示不確定的類型
T (type) 表示具體的一個(gè)java類型
K V (key value) 分別代表java鍵值中的Key Value
E (element) 代表Element

這些字母隨意使用,只是代表類型,也可以用單詞。

2、泛型的使用

泛型有三種使用方式,分別為:泛型類、泛型接口、泛型方法。

類的使用地方是

方法的使用地方

  • Java泛型類
  • Java泛型方法
  • Java泛型接口
/**
* @author 香菜
*/
public class Player<T> {// 泛型類
  private T name;
  public T getName() {
      return name;
  }
  public void setName(T name) {
      this.name = name;
  }
}
 
public class Apple extends Fruit {
  public <T> void getInstance(T t){// 泛型方法
      System.out.println(t);
  }
}
 
public interface Generator<T> {
      public T next();
  }
 

3、泛型原理,泛型擦除

3.1 IDEA 查看字節(jié)碼

1、創(chuàng)建Java文件,并編譯,確認(rèn)生成了class

圖片

2、idea ->選中Java 文件 ->View

圖片

3.2 泛型擦除原理

我們通過(guò)例子來(lái)看一下,先看一個(gè)非泛型的版本:

圖片

從字節(jié)碼可以看出,在取出對(duì)象的的時(shí)候我們做了強(qiáng)制類型轉(zhuǎn)換。

下面我們給出一個(gè)泛型的版本,從字節(jié)碼的角度來(lái)看看:

圖片

在編譯過(guò)程中,類型變量的信息是能拿到的。所以,set方法在編譯器可以做類型檢查,非法類型不能通過(guò)編譯。但是對(duì)于get方法,由于擦除機(jī)制,運(yùn)行時(shí)的實(shí)際引用類型為Object類型。為了“還原”返回結(jié)果的類型,編譯器在get之后添加了類型轉(zhuǎn)換。所以,在Player.class文件main方法主體第18行有一處類型轉(zhuǎn)換的邏輯。它是編譯器自動(dòng)幫我們加進(jìn)去的。

所以在泛型類對(duì)象讀取和寫入的位置為我們做了處理,為代碼添加約束。

泛型參數(shù)將會(huì)被擦除到它的第一個(gè)邊界(邊界可以有多個(gè),重用 extends 關(guān)鍵字,通過(guò)它能給與參數(shù)類型添加一個(gè)邊界)。編譯器事實(shí)上會(huì)把類型參數(shù)替換為它的第一個(gè)邊界的類型。如果沒(méi)有指明邊界,那么類型參數(shù)將被擦除到Object。

4、?和 T 的區(qū)別

?使用場(chǎng)景 和Object一樣,和C++的Void 指針一樣,基本上就是不確定類型,可以指向任何對(duì)象。一般用在引用。

T 是泛型的定義類型,在運(yùn)行時(shí)是確定的類型。

5、super extends

通配符限定:

<? extends T>:子類型的通配符限定,以查詢?yōu)橹?/strong>,比如消費(fèi)者集合場(chǎng)景

<? super T>:超類型的通配符限定,以添加為主,比如生產(chǎn)者集合場(chǎng)景

super 下界通配符 ,向下兼容子類及其子孫類, T super Child 會(huì)被擦除為 Object

extends 上界通配符 ,向下兼容子類及其子孫類, T extends Parent 會(huì)被擦除為 Parent

class Fruit {}
class Apple extends Fruit {}
class FuShi extends Apple {}
class Orange extends Fruit {}
import java.util.ArrayList;
import java.util.List;
public class Aain {
 public static void main(String[] args) {
       //上界
       List<? extends Fruit> topList = new ArrayList<Apple>();
       topList.add(null);
       //add Fruit對(duì)象會(huì)報(bào)錯(cuò)
       //topList.add(new Fruit());
       Fruit fruit1 = topList.get(0);
       //下界
       List<? super Apple> downList = new ArrayList<>();
       downList.add(new Apple());
       downList.add(new FuShi());
       //get Apple對(duì)象會(huì)報(bào)錯(cuò)
       //Apple apple = downList.get(0);
}

上界 <? extend Fruit> ,表示所有繼承Fruit的子類,但是具體是哪個(gè)子類,但是肯定是Fruit

下界 <? super Apple>,表示Apple的所有父類,包括Fruit,一直可以追溯到老祖宗Object 。

歸根結(jié)底可以用一句話表示,那就是編譯器可以支持向上轉(zhuǎn)型,但不支持向下轉(zhuǎn)型。具體來(lái)講,我可以把Apple對(duì)象賦值給Fruit的引用,但是如果把Fruit對(duì)象賦值給Apple的引用就必須得用cast。

6、注意點(diǎn)

1、靜態(tài)方法無(wú)法訪問(wèn)類的泛型

圖片

可以看到Idea 提示無(wú)法引用靜態(tài)上下文。

2、創(chuàng)建之后無(wú)法修改類型

List<Player> 無(wú)法插入其他的類型,已經(jīng)確定類型的不可以修改類型

3、類型判斷問(wèn)題

問(wèn)題:因?yàn)轭愋驮诰幾g完之后無(wú)法獲取具體的類型,所以在運(yùn)行時(shí)是無(wú)法判斷類的類型。

我們可以通過(guò)下面的代碼來(lái)解決泛型的類型信息由于擦除無(wú)法進(jìn)行類型判斷的問(wèn)題:

/**
* 判斷類型
* @author 香菜
* @param <T>
*/
public class GenClass<T> {
   Class<?> classType;
   public GenClass(Class<?> classType) {
       this.classType = classType;
  }
   public boolean isInstance(Object object){
       return classType.isInstance(object);
  }
}

解決方案:我們通過(guò)在創(chuàng)建對(duì)象的時(shí)候在構(gòu)造函數(shù)中傳入具體的class類型,然后通過(guò)這個(gè)Class對(duì)象進(jìn)行類型判斷。

4、創(chuàng)建類型實(shí)例

問(wèn)題:泛型代碼中不能new T()的原因有兩個(gè),一是因?yàn)椴脸?,不能確定類型;而是無(wú)法確定T是否包含無(wú)參構(gòu)造函數(shù)。

在之前的文章中,有一個(gè)需求是根據(jù)不同的節(jié)點(diǎn)配置實(shí)例化創(chuàng)建具體的執(zhí)行節(jié)點(diǎn),即根據(jù)IfNodeCfg 創(chuàng)建具體的IfNode.

/**
* 創(chuàng)建實(shí)例
* @author 香菜
*/
public abstract class AbsNodeCfg<T> {
   public abstract T getInstance();
}
public class IfNodeCfg extends AbsNodeCfg<IfNode>{
   @Override
   public IfNode getInstance() {
       return new IfNode();
  }
}
/**
* 創(chuàng)建實(shí)例
* @author 香菜
*/
public class IfNode {
}

解決方案:通過(guò)上面的方式可以根據(jù)具體的類型,創(chuàng)建具體的實(shí)例,擴(kuò)展的時(shí)候直接繼承AbsNodeCfg,并且實(shí)現(xiàn)具體的節(jié)點(diǎn)就可以了。

7、總結(jié)

泛型相當(dāng)于創(chuàng)建了一組的類,方法,虛擬機(jī)中沒(méi)有泛型類型對(duì)象的概念,在它眼里所有對(duì)象都是普通對(duì)象

圖片

本篇文章就到這里了,希望能給你帶來(lái)幫助,也希望您能夠多多關(guān)注腳本之家的更多內(nèi)容!

相關(guān)文章

  • 一文帶你了解Java8?Stream流處理中的收集器技巧

    一文帶你了解Java8?Stream流處理中的收集器技巧

    Java?8?引入的?Stream?極大地簡(jiǎn)化了集合數(shù)據(jù)的處理,提供了一種現(xiàn)代、函數(shù)式的方式來(lái)處理數(shù)據(jù),本文將深入探討?Java?8?Stream?中的收集器,希望對(duì)大家有所幫助
    2023-08-08
  • 使用SpringJPA?直接實(shí)現(xiàn)count(*)

    使用SpringJPA?直接實(shí)現(xiàn)count(*)

    這篇文章主要介紹了SpringJPA?直接實(shí)現(xiàn)count(*),具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2021-11-11
  • Java通過(guò)值查找對(duì)應(yīng)的枚舉的實(shí)現(xiàn)

    Java通過(guò)值查找對(duì)應(yīng)的枚舉的實(shí)現(xiàn)

    本文主要介紹了Java通過(guò)值查找對(duì)應(yīng)的枚舉的實(shí)現(xiàn),文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2022-02-02
  • 教你使用eclipse?搭建Swt?環(huán)境的全過(guò)程

    教你使用eclipse?搭建Swt?環(huán)境的全過(guò)程

    本文給大家分享使用eclipse?搭建Swt?環(huán)境的全過(guò)程,本文通過(guò)圖文并茂的形式給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2021-12-12
  • Spring+Hibernate+Struts(SSH)框架整合實(shí)戰(zhàn)

    Spring+Hibernate+Struts(SSH)框架整合實(shí)戰(zhàn)

    SSH是 struts+spring+hibernate的一個(gè)集成框架,是目前比較流行的一種Web應(yīng)用程序開源框架。本篇文章主要介紹了Spring+Hibernate+Struts(SSH)框架整合實(shí)戰(zhàn),非常具有實(shí)用價(jià)值,需要的朋友可以參考下
    2018-04-04
  • JVM內(nèi)置函數(shù)Intrinsics介紹

    JVM內(nèi)置函數(shù)Intrinsics介紹

    這篇文章主要介紹了JVM內(nèi)置函數(shù)Intrinsics,我們將學(xué)習(xí)什么是intrinsics(內(nèi)部/內(nèi)置函數(shù)),以及它們?nèi)绾卧贘ava和其他基于JVM的語(yǔ)言中工作,需要的朋友可以參考一下
    2022-02-02
  • Spring Boot開箱即用可插拔實(shí)現(xiàn)過(guò)程演練與原理解析

    Spring Boot開箱即用可插拔實(shí)現(xiàn)過(guò)程演練與原理解析

    本文通過(guò)深入探討Spring Boot的背景歷史、業(yè)務(wù)場(chǎng)景、功能點(diǎn)以及底層原理,并通過(guò)Java代碼手寫模擬了Spring Boot的啟動(dòng)過(guò)程和自動(dòng)配置功能,為開發(fā)者提供了一個(gè)全面的理解,感興趣的朋友跟隨小編一起看看吧
    2024-11-11
  • Java信號(hào)量Semaphore原理及代碼實(shí)例

    Java信號(hào)量Semaphore原理及代碼實(shí)例

    這篇文章主要介紹了Java信號(hào)量Semaphore原理及代碼實(shí)例,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下
    2020-10-10
  • Spring AOP統(tǒng)一功能處理示例代碼

    Spring AOP統(tǒng)一功能處理示例代碼

    AOP面向切面編程,它是一種思想,它是對(duì)某一類事情的集中處理,而AOP是一種思想,而Spring AOP是一個(gè)框架,提供了一種對(duì)AOP思想的實(shí)現(xiàn),它們的關(guān)系和loC與DI類似,這篇文章主要介紹了Spring AOP統(tǒng)一功能處理示例代碼,需要的朋友可以參考下
    2023-01-01
  • mybatis?foreach?list特殊處理方式

    mybatis?foreach?list特殊處理方式

    這篇文章主要介紹了mybatis?foreach?list特殊處理方式,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2022-03-03

最新評(píng)論

阿克| 九寨沟县| 化德县| 长海县| 象州县| 潍坊市| 白城市| 班玛县| 化德县| 绥中县| 思南县| 攀枝花市| 东宁县| 米林县| 富蕴县| 德惠市| 资中县| 荥经县| 南岸区| 东源县| 石嘴山市| 泰兴市| 株洲县| 青海省| 德江县| 孟州市| 富顺县| 汤原县| 寻甸| 兴和县| 同江市| 阿拉尔市| 萨嘎县| 包头市| 江山市| 南涧| 平利县| 波密县| 林口县| 台南市| 白水县|