欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

一篇文章帶你搞定JAVA泛型

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

1、泛型的概念

泛型的作用就是把類型參數(shù)化,也就是我們常說的類型參數(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的類型,是不固定的

泛型常見的字母有以下:

? 表示不確定的類型
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 泛型擦除原理

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

圖片

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

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

圖片

在編譯過程中,類型變量的信息是能拿到的。所以,set方法在編譯器可以做類型檢查,非法類型不能通過編譯。但是對(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)鍵字,通過它能給與參數(shù)類型添加一個(gè)邊界)。編譯器事實(shí)上會(huì)把類型參數(shù)替換為它的第一個(gè)邊界的類型。如果沒有指明邊界,那么類型參數(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)型。具體來講,我可以把Apple對(duì)象賦值給Fruit的引用,但是如果把Fruit對(duì)象賦值給Apple的引用就必須得用cast。

6、注意點(diǎn)

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

圖片

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

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

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

3、類型判斷問題

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

我們可以通過下面的代碼來解決泛型的類型信息由于擦除無法進(jì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);
  }
}

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

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

問題:泛型代碼中不能new T()的原因有兩個(gè),一是因?yàn)椴脸?,不能確定類型;而是無法確定T是否包含無參構(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 {
}

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

7、總結(jié)

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

圖片

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

相關(guān)文章

  • SpringBoot結(jié)合Tess4J實(shí)現(xiàn)拍圖識(shí)字的示例代碼

    SpringBoot結(jié)合Tess4J實(shí)現(xiàn)拍圖識(shí)字的示例代碼

    圖片中的文字提取已經(jīng)越來越多地應(yīng)用于數(shù)據(jù)輸入和自動(dòng)化處理過程,本文主要介紹了SpringBoot結(jié)合Tess4J實(shí)現(xiàn)拍圖識(shí)字的示例代碼,具有一定的參考價(jià)值,感興趣的可以了解一下
    2024-06-06
  • Mybatis下動(dòng)態(tài)sql中##和$$的區(qū)別講解

    Mybatis下動(dòng)態(tài)sql中##和$$的區(qū)別講解

    今天小編就為大家分享一篇關(guān)于Mybatis下動(dòng)態(tài)sql中##和$$的區(qū)別講解,小編覺得內(nèi)容挺不錯(cuò)的,現(xiàn)在分享給大家,具有很好的參考價(jià)值,需要的朋友一起跟隨小編來看看吧
    2019-03-03
  • SpringBoot整合Swagger3的流程詳解

    SpringBoot整合Swagger3的流程詳解

    這篇文章主要介紹了SpringBoot整合Swagger3的流程詳解,Swagger最核心的類就是Docket、它可以配置作者信息、掃描類型,在SwaggerConfig配置類,添加@Configuration和@EnableOpenApi注解,需要的朋友可以參考下
    2024-01-01
  • SpringBoot實(shí)現(xiàn)自定義線程池的方法

    SpringBoot實(shí)現(xiàn)自定義線程池的方法

    這篇文章主要介紹了SpringBoot中的自定義線程池解析,實(shí)現(xiàn)自定義線程池重寫spring默認(rèn)線程池的方式使用的時(shí)候,只需要加@Async注解就可以,不用去聲明線程池類,需要的朋友可以參考下
    2023-11-11
  • 如何開啟控制臺(tái)輸出mybatis執(zhí)行的sql日志問題

    如何開啟控制臺(tái)輸出mybatis執(zhí)行的sql日志問題

    這篇文章主要介紹了如何開啟控制臺(tái)輸出mybatis執(zhí)行的sql日志問題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2023-09-09
  • 使用@DS輕松解決動(dòng)態(tài)數(shù)據(jù)源的問題

    使用@DS輕松解決動(dòng)態(tài)數(shù)據(jù)源的問題

    這篇文章主要介紹了使用@DS輕松解決動(dòng)態(tài)數(shù)據(jù)源的問題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2022-05-05
  • java調(diào)用chatgpt接口來實(shí)現(xiàn)專屬于自己的人工智能助手

    java調(diào)用chatgpt接口來實(shí)現(xiàn)專屬于自己的人工智能助手

    這篇文章主要介紹了用java來調(diào)用chatget的接口,實(shí)現(xiàn)自己的聊天機(jī)器人,對(duì)人工智能感興趣的小伙伴可以參考閱讀
    2023-03-03
  • Springboot @Value獲取值為空問題解決方案

    Springboot @Value獲取值為空問題解決方案

    這篇文章主要介紹了Springboot @Value獲取值為空問題解決方案,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下
    2020-02-02
  • Spring Boot接口限流的常用算法及特點(diǎn)

    Spring Boot接口限流的常用算法及特點(diǎn)

    這篇文章主要給大家介紹了關(guān)于Spring Boot接口限流的常用算法及特點(diǎn)的相關(guān)資料,文中通過圖文介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2021-02-02
  • mybatis-plus指定字段模糊查詢的實(shí)現(xiàn)方法

    mybatis-plus指定字段模糊查詢的實(shí)現(xiàn)方法

    最近項(xiàng)目中使用springboot+mybatis-plus來實(shí)現(xiàn),所以下面這篇文章主要給大家介紹了關(guān)于mybatis-plus實(shí)現(xiàn)指定字段模糊查詢的相關(guān)資料,需要的朋友可以參考下
    2022-04-04

最新評(píng)論