Java泛型解析,了解泛型使用

2020-12-13 一刻動畫

Java 泛型

泛型的本質是參數化類型。簡單解釋就是,將參數的數據類型也當作參數對待。泛型的目的就是為了寫一套代碼,可以到處通用,不用擔心類型安全的問題。泛型可以用在類、接口、方法中對應的就是泛型類、泛型接口和泛型方法。

一、為什麼要引入泛型?

我們先看一個例子:

獲取一個字符串對象,列印如下:

引入 Object 類型

這個類只能適用字符串類型,那要獲取整型等其他數據類型怎麼辦呢?於是我們想到了 Object 類型,它可以表示所有 Java 類類型數據,於是改造下:

列印結果,字符串類型和上面的列印結果是相同的:

讓方法返回一個 Object 類型數據,這樣似乎就解決了問題。但還是有個問題,因為方法返回的是 Object 類,返回值參與其它類型數據的計算時需要強制類型轉換。如:

使用泛型

Object 類型數據使用時需要事先知道參與計算的具體類型,有時候我們很難判斷需要什麼類型,如果寫錯了,那就會報錯。為了少寫代碼,且不出錯,於是就引入了泛型。通過泛型改造上面的類:

列印結果:

使用泛型後就不用強制轉換數據類型,代碼也變得通用了。

泛型的定義

使用泛型的方式有3種,分別是:

泛型類泛型方法泛型接口上面的代碼中用的是 T 來代指數據類型,也就是泛型參數。T 不是唯一的,可以用任意大寫字母替代,不過一般遵循如下原則:T:指一般的任何類。E:元素 Element 的意思,或者 Exception 異常的意思。K:鍵,Key 的意思。V:值,Value 的意思,通常與 K 一起配合使用。

泛型類,定義一個泛型類:

在類名後面需要用<>包裹,T 就是類型參數,多個類型參數,用不同的大寫字母且「,」分隔。創建泛型類:

<>中傳入對應的類型,類中的 T 就會被對應的類型取代。

泛型方法,定義一個泛型方法:

泛型方法的定義是在返回類型前面加<T>,返回類型也可以用泛型代指,如 T。方法中的類型化參數 T 不用<>。沒有返回類型的泛型方法:

泛型類和泛型方法可以同時使用,如:

泛型方法和普通方法的參數沒有關聯。

泛型接口

定義泛型接口:

泛型接口和泛型類的定義類似。

泛型通配符?

有時我們會碰到這樣的情況,一個夫類型的集合需要兼容子類,或者子類集合要兼容父類。如:

Integer繼承自Number 類,但不代表 List<Integer>繼承自 List<Number>,泛型也沒有繼承關係,所以不能像變量類型一樣兼容使用。但有時會又這類需求,於是引入?通配符:

<? extends T>上限通配符,指類型必須是 T 的子類,或 T 類型。

<? super T>下限通配符,指類型必須是 T 的父類,或 T 類型。 如:

還有一種是無限通配符:<?>本質是<? extends Object>,表示不知道什麼類型。

無限通配符可以方便使用但也是有限制的,無限通配符意味著不知道具體類型,所以數據只能讀取,不能寫入。如:

類型擦除

泛型只在編譯階段有效,編譯後類型會被擦除。如:

列印結果為 true,也即 l1 和 l2 的類型相同,都是java.util.ArrayList,泛型信息被擦除了。

泛型的限制

泛型不支持 8 中基本數據類型,需要用對應類型的包裝類。

List<int> l = new ArrayList<>(); // 編譯報錯

創建泛型類數組時只能創建無限定通配符的。

因為類型擦除後就不知道數組中具體存儲的哪種類型數據了。

泛型與反射

先看個例子:

創建一個接受Integer類型的泛型數組 list,如果往 list 中插入String類型數據時編譯出錯,類型限制。看下 List 的 add 方法:

E代表任意類型,所以類型擦除後 add 方法就變成了如下方式:

boolean add(Object obj);

通過反射可以獲取對象實例,並訪問對象數據。如:

因為泛型的類型擦除性質,利用反射就可以繞過編譯器的類型檢查,這也說明了反射會引入安全問題,需要謹慎使用。

相關焦點

  • Java之使用泛型與未使用泛型的區別
    各位小夥伴們大家好,在之前的文章中,小編有介紹過Java之泛型的概念,這次小編要介紹的是,Java程序中,使用泛型與未使用泛型的區別。代碼如下:public class Demo01Generic {public static void main(String[] args) { show01(); show02(); } /*創建集合對象,使用泛型好處:1.避免了類型轉換的麻煩,存儲的是什麼類型的數據,取出的就是什麼類型的數據 2.把運行期異常
  • Java泛型的特點與優缺點,泛型擦除是怎麼回事?
    Java 是如何支持泛型的?底層實現?是否了解 Java 泛型的特點,優缺點?是否了解泛型擦除?考察的知識點Java 是如何支持泛型的?底層實現機制是什麼?首先,Java 語言中的泛型不能接受基本類型作為類型參數-它只能接受引用類型。這意味著可以定 List<Integer>,但是不可以定義 List<int>。其次,在 C++ 模板中,編譯器使用提供的類型參數來生成不同代碼。而 Java 中的泛型,編譯器僅僅對這些類型參數進行擦除和替換。
  • Java反射,泛型在Json中的運用
    最近項目中遇到了Json數據自動獲取的功能,不然令人想起java的反射,已經很長時間沒複習java了正好一塊連java的這一塊內容一起過一遍。java中的反射無疑就相當於java開發者的春天,在眾多的框架中也能看到它的身影,可以在運行時檢查類,接口、變量和方法等信息,可以實例化調用方法以及設置變量值等。本文主要以代碼的形式直接將反射,泛型的運用展現出來。java中的反射首先新建一個基礎類Author。
  • Java 泛型詳解-絕對是對泛型方法講解最詳細的,沒有之一
    的泛型特性的了解僅限於表面的淺淺一層,直到在學習設計模式時發現有不了解的用法,才想起詳細的記錄一下。本文參考java 泛型詳解、Java中的泛型方法、 java泛型詳解概述泛型在java中有很重要的地位,在面向對象編程及各種設計模式中有非常廣泛的應用。什麼是泛型?為什麼要使用泛型?泛型,即「參數化類型」。一提到參數,最熟悉的就是定義方法時有形參,然後調用此方法時傳遞實參。那麼參數化類型怎麼理解呢?
  • 泛型Java程式設計師必備基礎
    表示不確定的 java 類型T (type) 表示具體的一個java類型K V (key value) 分別代表java鍵值中的Key ValueE (element) 代表Element為什麼需要引入通配符呢,我們先來看一個例子:
  • Java泛型總結
    什麼是泛型泛型是jdk5引入的類型機制,就是將類型參數化,它是早在1999年就制定的jsr14的實現。泛型機制將類型轉換時的類型檢查從運行時提前到了編譯時,使用泛型編寫的代碼比雜亂的使用object並在需要時再強制類型轉換的機制具有更好的可讀性和安全性。
  • java泛型的基本使用案例,重基礎
    持續更新中……在上幾篇圖文中已經介紹了容器集合的大部分的基本使用,接下來按照知識圖譜的順序來介紹一下java泛型的使用。在下面的例子中講創建一個繼承結構,然後用基本類型的類型來聲明容器,看看容器表現是否表現正常,並且創建一個泛型方法,來觀察對類型的處理。下面通過代碼展示:
  • Java總結篇系列:Java泛型
    2.因此,//1處取出集合元素時需要人為的強制類型轉化到具體的目標類型,且很容易出現「java.lang.ClassCastException」異常。那麼有沒有什麼辦法可以使集合能夠記住集合內元素各類型,且能夠達到只要編譯時不出現問題,運行時就不會出現「java.lang.ClassCastException」異常呢?答案就是使用泛型。二.什麼是泛型?
  • JAVA總結篇系列-泛型
    2.因此,//1處取出集合元素時需要人為的強制類型轉化到具體的目標類型,且很容易出現「java.lang.ClassCastException」異常。那麼有沒有什麼辦法可以使集合能夠記住集合內元素各類型,且能夠達到只要編譯時不出現問題,運行時就不會出現「java.lang.ClassCastException」異常呢?答案就是使用泛型。
  • 為什麼我們需要Java中的泛型類型?
    泛型類型在Java集合中廣泛使用。為什麼我們需要Java中的泛型類型?理解這個問題可以幫助我們更好地理解許多相關概念。在本文中,我將使用一個非常簡短的示例來說明Generic為什麼有用。1.泛型概述實現泛型的目的是在編譯時而不是運行時中發現錯誤。在編譯時查找錯誤可以節省調試Java程序的時間,因為編譯時錯誤更容易查找和修復。泛型類型僅在編譯時存在。這是學習Java泛型時要記住的最重要的事情。2.如果沒有泛型怎麼辦?
  • Java 泛型詳解
    }    public String get() { return object; }}這是最常見的做法,這樣做的一個壞處是Box裡面現在只能裝入String類型的元素,今後如果我們需要裝入Integer等其他類型的元素,還必須要另外重寫一個Box,代碼得不到復用,使用泛型可以很好的解決這個問題。
  • Java面試重要考點攻克:如何在Java中使用泛型?
    正確理解泛型對於掌握Java至關重要,這也會對你的面試有所助益。本文是關於Java中泛型知識的大放送,泛型是什麼,如何在Java中使用,以及它們的優點有哪些,你都能在下文中找到答案。在Java 5中添加泛型是為了提供編譯時類型檢查,並消除使用集合類時常見的 ClassCastException 風險。
  • Java泛型簡單的使用
    Java裡面的泛型在實際開發中運用的很多,學過C++的同學一定知道C++的模板,而Java中的泛型,一定程度上和它還是挺像的。
  • 計算機泛型
    當我們不知道往集合裡面放入什麼數據時候,當這種情況出現時,我們考慮的就是泛型。何為泛型?通俗點說:一個模型,不固定的模型,但我們要提前準備好這個模型,如果對應遊戲裡面的規則的話,就是所謂的預判,我們把這個模型準備了,當我們需要用到的時候,直接使用這個模型改造成自己想要的模樣。
  • Java 泛型背後的原理
    作者 | 的一幕  來源 | https://www.jianshu.com/p/dd34211f2565這一節主要講的內容是java中泛型的應用,通過該篇讓大家更好地理解泛型,以及面試中經常說的泛型類型擦除是什麼概念,今天就帶著這幾個問題一起看下:舉一個簡單的例子:這裡可以看出來在代碼編寫階段就已經報錯了,不能往string類型的集合中添加int類型的數據。
  • Java泛型背後是什麼
    這一節主要講的內容是java中泛型的應用,通過該篇讓大家更好地理解泛型,以及面試中經常說的泛型類型擦除是什麼概念,今天就帶著這幾個問題一起看下:舉一個簡單的例子:這裡可以看出來在代碼編寫階段就已經報錯了,不能往string類型的集合中添加int類型的數據。
  • Java的「泛型」特性,你以為自己會了?(萬字長文)
    定義在了解一個事物之前,我們必定要先知道他的定義,所以我們就從定義開始,去一步一步揭開泛型的神秘面紗。同時對於編譯器也帶來了一定的增強,為了支持泛型,java的類庫都做相應的修改以支持泛型的特性。(科普:實際上java泛型並不是 jdk5(2004發布了jdk5) 才提出來的,早在1999年的時候,泛型機制就是java最早的規範之一)另外,泛型還具有以下的優點:# 1.提交了ja
  • Java基礎教程:Java泛型概述及應用(Java難點)
    因此在JDK5之後,新增了泛型(Generic)語法,讓你在設計API時可以指定類或方法支持泛型,這樣我們使用API的時候也變得更為簡潔,並得到了編譯時期的語法檢查。泛型:可以在類或方法中預支地使用未知的類型。
  • Java泛型的約束與局限性
    Pair,類型擦除會使這種不同類檢查機制無效,這就是不能實例化泛型數組的原因!:通過泛型數組包裝器,如ArrayList類,維護一個Object數組,然後通過進出口方法set、get來限定類型和強制轉換數組類型,從而間接實現泛型數組,例如:ArrayList: ArrayList<Pair<T>>、ArrayList<T>不能實例化類型變量T即不能使用new T(..)
  • 理解泛型中的in和out
    |  1.引言  |Kotlin中的泛型使用和java一樣,但如果你使用的是kotlin語言開發,你會發現kotlin的泛型會多出兩個關鍵字,分別是in和out。這兩個關鍵字經常讓人疑惑,它的字面意思是輸入和輸出,很難讓人聯想到java泛型的某個特性。實際上它們在java中是有對應關係的。