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

Java泛型中通配符T、E、K、V、?的深入理解

 更新時(shí)間:2026年05月06日 10:01:02   作者:鏡花水月linyi  
Java泛型(generics)是JDK 5中引入的一個(gè)新特性, 泛型提供了編譯時(shí)類型安全檢測(cè)機(jī)制,該機(jī)制允許開發(fā)者在編譯時(shí)檢測(cè)到非法的類型,這篇文章主要介紹了Java泛型中通配符T、E、K、V、?的相關(guān)資料,需要的朋友可以參考下

前言

不久前,被人問(wèn)到Java 泛型中的通配符 T,E,K,V,? 是什么?有什么用?這不經(jīng)讓我有些回憶起該開始學(xué)習(xí)Java那段日子,那是對(duì)泛型什么的其實(shí)有些迷迷糊糊的,學(xué)的不這么樣,是在做項(xiàng)目的過(guò)程中,漸漸有又看到別人的代碼、在看源碼的時(shí)候老是遇見,之后就專門去了解學(xué)習(xí),才對(duì)這幾個(gè)通配符 T,E,K,V,?有所了解。

泛型有什么用?

在介紹這幾個(gè)通配符之前,我們先介紹介紹泛型,看看泛型帶給我們的好處。
Java泛型是JDK5中引入的一個(gè)新特性,泛型提供了編譯是類型安全檢測(cè)機(jī)制,這個(gè)機(jī)制允許開發(fā)者在編譯是檢測(cè)非法類型。泛型的本質(zhì)就是參數(shù)化類型,就是在編譯時(shí)對(duì)輸入的參數(shù)指定一個(gè)數(shù)據(jù)類型。

  1. 類型安全:編譯是檢查類型是否匹配,避免了ClassCastexception的發(fā)生。
  // 非泛型寫法(存在類型轉(zhuǎn)換風(fēng)險(xiǎn))
  List list1 = new ArrayList();
  list1.add("a");
  Integer num = (Long) list1.get(0);  // 運(yùn)行時(shí)拋出 ClassCastException

  // 泛型寫法(編譯時(shí)檢查類型)
  List<String> list2 = new ArrayList<>();
  // list.add(1);       // 編譯報(bào)錯(cuò)
  list2.add("a");
  String str = list2.get(0); // 無(wú)需強(qiáng)制轉(zhuǎn)換 
  1. 消除代碼強(qiáng)制類型轉(zhuǎn)換:減少了一些類型轉(zhuǎn)換操作。
// 非泛型寫法
Map map1 = new HashMap();
map1.put("user", new User());
User user1 = (User) map1.get("user");

// 泛型寫法
Map<String, User> map2 = new HashMap<>();
map2.put("user", new User());
// 自動(dòng)轉(zhuǎn)換
User user2 = map2.get("user");

3.代碼復(fù)用:可以支持多種數(shù)據(jù)類型,不要重復(fù)編寫代碼,例如:我們常用的統(tǒng)一響應(yīng)結(jié)果類。

@Data
@NoArgsConstructor
@AllArgsConstructor
public class Result<T> {
    /**
     * 響應(yīng)狀態(tài)碼
     */
    private int code;

    /**
     * 響應(yīng)信息
     */
    private String message;

    /**
     * 響應(yīng)數(shù)據(jù)
     */
    private T data;

    /**
     * 時(shí)間戳
     */
    private long timestamp;
    其他代碼省略...
  1. 增強(qiáng)可讀性:通過(guò)類型參數(shù)就直接能看出要填入什么類型。
List<String> list = new ArrayList<>();

泛型里的通配符

我們?cè)谑褂梅盒偷臅r(shí)候,經(jīng)常會(huì)使用或者看見多種不同的通配符,常見的 T,E,K,V,?這幾種,相信大家一定不陌生,但是真的問(wèn)你他們有什么作用?有什么區(qū)別時(shí),很多人應(yīng)該是不能很好的介紹它們的,接下來(lái)我就來(lái)給大家介紹介紹。

T,E,K,V

  1. T(Type) T表示任意類型參數(shù),我們舉個(gè)例子
pubile class A<T>{
    prvate T t;
    //其他省略...
}

//創(chuàng)建一個(gè)不帶泛型參數(shù)的A
    A a = new A();
    a.set(new B());
    B b = (B) a.get();//需要進(jìn)行強(qiáng)制類型轉(zhuǎn)換

//創(chuàng)建一個(gè)帶泛型參數(shù)的A
    A<B> a = new A<B>();
    a.set(new B());
    B b = a.get();
  1. E(Element) E表示集合中的元素類型
List<E> list = new ArrayList<>();
  1. K(Key) K表示映射的鍵的數(shù)據(jù)類型
Map<K,V> map = new HashMap<>();
  1. V(Value) V表示映射的值的數(shù)據(jù)類型
Map<K,V> map = new HashMap<>();

通配符 ?

  1. 無(wú)界通配符 <?> 表示未知類型,接收任意類型
   // 使用無(wú)界通配符處理任意類型的查詢結(jié)果
   public void logQueryResult(List<?> resultList) {
       resultList.forEach(obj -> log.info("Result: {}", obj));
   }
  1. 上界通配符 <? extends T> 表示類型是T或者是子類
 // 使用上界通配符讀取緩存
   public <T extends Serializable> T getCache(String key, Class<T> clazz) {
       Object value = redisTemplate.opsForValue().get(key);
       return clazz.cast(value);
   }
  1. 下界通配符 <? super T> 表示類型是T或者是父類
  // 使用下界通配符寫入緩存
   public void setCache(String key, <? super Serializable> value) {
       redisTemplate.opsForValue().set(key, value);
   }

綜合示例:

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

public class Demo {
    //實(shí)體類
    class Animal {
        void eat() {
            System.out.println("Animal is eating");
        }
    }

    class Dog extends Animal {
        @Override
        void eat() {
            System.out.println("Dog is eating");
        }
    }

    class Husky extends Dog {
        @Override
        void eat() {
            System.out.println("Husky is eating");
        }
    }

    /**
     * 無(wú)界通配符 <?>
     */
    // 只能讀取元素,不能寫入(除null外)
    public static void printAllElements(List<?> list) {
        for (Object obj : list) {
            System.out.println(obj);
        }
        // list.add("test");  // 編譯錯(cuò)誤!無(wú)法寫入具體類型
        list.add(null);       // 唯一允許的寫入操作
    }

    /**
     * 上界通配符 <? extends T>
     */ 
    // 安全讀取為Animal,但不能寫入(生產(chǎn)者場(chǎng)景)
    public static void processAnimals(List<? extends Animal> animals) {
        for (Animal animal : animals) {
            animal.eat();
        }
        // animals.add(new Dog());  // 編譯錯(cuò)誤!無(wú)法確定具體子類型
    }

    /**
     * 下界通配符 <? super T>
     */ 
    // 安全寫入Dog,讀取需要強(qiáng)制轉(zhuǎn)換(消費(fèi)者場(chǎng)景)
    public static void addDogs(List<? super Dog> dogList) {
        dogList.add(new Dog());
        dogList.add(new Husky()); // Husky是Dog子類
        // dogList.add(new Animal()); // 編譯錯(cuò)誤!Animal不是Dog的超類
        
        Object obj = dogList.get(0); // 讀取只能為Object
        if (obj instanceof Dog) {
            Dog dog = (Dog) obj;     // 需要顯式類型轉(zhuǎn)換
        }
    }

    public static void main(String[] args) {
        // 測(cè)試無(wú)界通配符
        List<String> strings = List.of("A", "B", "C");
        printAllElements(strings);

        List<Integer> integers = List.of(1, 2, 3);
        printAllElements(integers);

        // 測(cè)試上界通配符
        List<Dog> dogs = new ArrayList<>();
        dogs.add(new Dog());
        processAnimals(dogs);

        List<Husky> huskies = new ArrayList<>();
        huskies.add(new Husky());
        processAnimals(huskies);

        // 測(cè)試下界通配符
        List<Animal> animals = new ArrayList<>();
        addDogs(animals);
        System.out.println(animals);

        List<Object> objects = new ArrayList<>();
        addDogs(objects);
    }
}

我們需要清楚,這些只是我們開發(fā)過(guò)程中約定,不是強(qiáng)制規(guī)定,但遵循它們可以提高代碼的可讀性。

總結(jié)

我們?cè)诤芏鄷r(shí)候只是單純的會(huì)使用某些技術(shù),但是對(duì)它們里面許許多多常見的都是一知半解的,只是會(huì)使用確實(shí)很重要,但是如果有時(shí)間,我們不妨好好的在對(duì)這些技術(shù)進(jìn)行深入學(xué)習(xí),不僅知其然,而且知其所以然,這樣我們的技術(shù)才會(huì)不斷提升進(jìn)步。

到此這篇關(guān)于Java泛型中通配符T、E、K、V、?的文章就介紹到這了,更多相關(guān)Java泛型通配符T、E、K、V、??jī)?nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • 詳解Java8中Optional的常見用法

    詳解Java8中Optional的常見用法

    Opitonal是java8引入的一個(gè)新類,目的是為了解決空指針異常問(wèn)題。本文將通過(guò)示例為大家詳細(xì)講講Optional的常見用法,需要的可以參考一下
    2022-09-09
  • Java中的Switch?Case語(yǔ)句及示例詳解

    Java中的Switch?Case語(yǔ)句及示例詳解

    Java中的SwitchCase語(yǔ)句用于處理多個(gè)選項(xiàng),本文結(jié)合實(shí)例代碼給大家介紹Java中的Switch?Case語(yǔ)句及示例,感興趣的朋友跟隨小編一起看看吧
    2026-01-01
  • SpringBoot實(shí)現(xiàn)文件記錄日志及日志文件自動(dòng)歸檔和壓縮

    SpringBoot實(shí)現(xiàn)文件記錄日志及日志文件自動(dòng)歸檔和壓縮

    Logback是Java日志框架,通過(guò)Logger收集日志并經(jīng)Appender輸出至控制臺(tái)、文件等,SpringBoot配置logback-spring.xml可實(shí)現(xiàn)日志文件存儲(chǔ),本文給大家介紹了SpringBoot實(shí)現(xiàn)文件記錄日志及日志文件自動(dòng)歸檔和壓縮,需要的朋友可以參考下
    2025-05-05
  • JNDI,JTA和JMS簡(jiǎn)介

    JNDI,JTA和JMS簡(jiǎn)介

    這篇文章主要介紹了JNDI,JTA和JMS的相關(guān)內(nèi)容,包括中文釋義,概念解釋等,需要的朋友可以了解下。
    2017-09-09
  • Java實(shí)現(xiàn)圖像分割功能

    Java實(shí)現(xiàn)圖像分割功能

    這篇文章主要為大家詳細(xì)介紹了Java實(shí)現(xiàn)圖像分割功能,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2021-06-06
  • Springboot整合Flowable6.x導(dǎo)出bpmn20的步驟詳解

    Springboot整合Flowable6.x導(dǎo)出bpmn20的步驟詳解

    這篇文章主要介紹了Springboot整合Flowable6.x導(dǎo)出bpmn20,Flowable流程引擎可用于部署B(yǎng)PMN 2.0流程定義,可以十分靈活地加入你的應(yīng)用/服務(wù)/構(gòu)架,本文給出兩種從flowable導(dǎo)出流程定義bpmn20.xml的方式,需要的朋友可以參考下
    2023-04-04
  • 關(guān)于SpringBoot Actuator漏洞補(bǔ)救方案

    關(guān)于SpringBoot Actuator漏洞補(bǔ)救方案

    SpringBoot Actuator模塊提供了健康檢查,審計(jì),指標(biāo)收集,HTTP 跟蹤等,是幫助我們監(jiān)控和管理SpringBoot應(yīng)用的模塊,本文將主要介紹SpringBoot Actuator漏洞的補(bǔ)救方案,需要的朋友可以參考下
    2023-06-06
  • My eclipse 端口占用(9360)問(wèn)題解決辦法

    My eclipse 端口占用(9360)問(wèn)題解決辦法

    這篇文章主要介紹了My eclipse 工程發(fā)布時(shí)出現(xiàn)端口占用問(wèn)題解決辦法的相關(guān)資料,需要的朋友可以參考下
    2016-12-12
  • MP(MyBatis-Plus)實(shí)現(xiàn)樂(lè)觀鎖更新功能的示例代碼

    MP(MyBatis-Plus)實(shí)現(xiàn)樂(lè)觀鎖更新功能的示例代碼

    這篇文章主要介紹了MP(MyBatis-Plus)實(shí)現(xiàn)樂(lè)觀鎖更新功能的示例代碼,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2021-01-01
  • 詳解springboot啟動(dòng)時(shí)是如何加載配置文件application.yml文件

    詳解springboot啟動(dòng)時(shí)是如何加載配置文件application.yml文件

    這篇文章主要介紹了詳解springboot啟動(dòng)時(shí)是如何加載配置文件application.yml文件,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2020-06-06

最新評(píng)論

伊春市| 瑞安市| 和平区| 平和县| 玉树县| 利津县| 崇信县| 永昌县| 额敏县| 弥渡县| 丁青县| 绥中县| 罗田县| 浦城县| 城固县| 长阳| 大城县| 奉节县| 乐至县| 嘉黎县| 日喀则市| 石棉县| 清苑县| 开江县| 赤壁市| 乌恰县| 宜州市| 安龙县| 汽车| 康马县| 古丈县| 扎鲁特旗| 望都县| 潜山县| 商河县| 临潭县| 芜湖县| 上栗县| 荆门市| 汶上县| 昭觉县|