圖文詳解 Java 泛型,寫得太好了!

来源:https://www.cnblogs.com/javastack/archive/2022/08/25/16625161.html
-Advertisement-
Play Games

泛型—— 一種可以接收數據類型的數據類型,本文將通俗講解Java泛型的優點、方法及相關細節。 一、泛型的引入 我們都知道,繼承是面向對象的三大特性之一,比如在我們向集合中添加元素的過程中add()方法里填入的是Object類,而Object又是所有類的父類,這就產生了一個問題——添加的類型無法做到統 ...


泛型—— 一種可以接收數據類型的數據類型,本文將通俗講解Java泛型的優點、方法及相關細節。

一、泛型的引入

我們都知道,繼承是面向對象的三大特性之一,比如在我們向集合中添加元素的過程中add()方法里填入的是Object類,而Object又是所有類的父類,這就產生了一個問題——添加的類型無法做到統一 由此就可能產生在遍歷集合取出元素時類型不統一而報錯問題。

例如:我向一個ArrayList集合中添加Person類的對象,但是不小心手賤添加了一個Boy類的對象,這就會導致如下結果

傳統的方式不能對加入到集合ArrayList中的數據類型進行約束(不安全)遍歷的時候,需要進行類型轉換,如果集合中的數據量較大,對效率有影響 這就極大地降低了程式的健壯性,因此設計者針對此問題引入了泛型!

更多集合系列教程:https://www.javastack.cn/categories/Java/

二、使用泛型的好處

1.提升了程式的健壯性和規範性

針對上述問題,當我們採用泛型就會顯得非常簡單,只需要在編譯類型後利用泛型指定一個特定類型,編譯器就會自動檢測出不符合規範的類並拋出錯誤提示

2.編譯時,檢查添加元素的類型,提高了安全性

3.減少了類型轉換的次數,提高效率

  • 當不使用泛型時:

  • 當使用泛型時:

4.在類聲明時通過一個標識可以表示屬性類型、方法的返回值類型、參數類型

class Person<E> {
    E s;   //可以是屬性類型
    public Person(E s) {  //可以是參數類型
        this.s = s;
    }
    public E f() { //可以是返回類型
        return s;
    }
    public void show() {
        System.out.println(s.getClass());  //顯示S的運行類型
    }
}

可以這樣理解:上述的class Person< E >中的“E”相當於這裡的E是一個軀殼 占位用的 以後定義的時候程式員可以自己去自定義

就像這樣

public static void main(String[] args) {
    Person<String> person1 = new Person<String>("xxxx");// E->String
    person.show();
    Person<Integer> person2 = new Person<Integer>(123); // E->Integer
    person.show();
}
運行結果:
class java.lang.String
class java.lang.Integer

三、泛型常見用法

1.定義泛型介面

曾經寫介面的時候都沒有定義泛型,它預設的就是Object類,其實這樣寫是不規範的!

如果說介面的存在是一種規範,那泛型介面就是規範中的規範

interface Im<U,R>{
    void hi(R r);
    void hello(R r1,R r2,U u1,U u2);
    default R method(U u){
        return null;
    }
}

在上述的泛型介面中已經規定傳入其中的必須是U,R類的對象,那麼當我們傳入其他類的對象時就會報錯,如圖:

根據規則,當我們實現介面時,就必須實現他的所有方法,而在這時我們就可以向<U,R>中傳入我們自己規定的類。在IDEA中重寫介面中的方法時,編譯器會自動將<U,R>替換成我們事先規定的類。

2.定義泛型集合

1.使用泛型方式給HashSet中放入三個學生對象,並輸出對象信息

 HashSet<Student> students = new HashSet<Student>();
 students.add(new Student("懶羊羊",21));
 students.add(new Student("喜羊羊",41));
 students.add(new Student("美羊羊",13));
 for (Student student :students) {
     System.out.println(student);
 }

上述的 泛型中Student的是我事先定義好的一個類,把它放到其中作為泛型來約束傳入的對象,以及在遍歷時減少轉型的次數提高效率

2.使用泛型方式給HashMap中放入三個學生對象,並輸出對象信息

HashMap<String, Student> hm = new HashMap<String, Student>();
// K-> String  V->Student與下麵的對應
hm.put("001",new Student("喜羊羊",21));
hm.put("002",new Student("懶羊羊",32));
hm.put("003",new Student("美羊羊",43));
Set<Map.Entry<String,Student>> ek=hm.entrySet();
Iterator<Map.Entry<String, Student>> iterator = ek.iterator();//取出迭代器
while (iterator.hasNext()) {
    Map.Entry<String, Student> next =  iterator.next();
    System.out.println(next.getKey()+" - "+next.getValue());
}

HashMap是一個雙列集合,以[K-V]的方式存儲對象,因此在使用泛型時要向其中傳入兩個類型

我們都知道使用迭代器遍歷HashMap時要先通過entrySet()取出鍵值對,然後通過轉型得到對應的類來得到對象信息。而在使用泛型定義[K-V]就規定了取出的鍵值對的類型,所以就省去了轉型這一步驟,同樣也使程式變得簡單,高效

四、泛型使用細節

1.<>中類型規範

2.繼承性體現

在給泛型指定具體類型後,可以傳入該類型或者其子類類型

P<A> ap = new P<A>(new A());
P<A> ap1 = new P<A>(new B()); //A的子類
class A {}
class B extends A{}

3.簡寫形式

 P<A> ap = new P(new A());

五、自定義泛型

1.自定義方法使用類聲明的泛型

在形參列表中傳入的數據類型與泛型不一致時會報錯,體現規範性

public static void main(String[] args) {
    U<String, Double, Integer> u = new U<>();
    u.hi("hello", 1.0);  //X->String Y->Double
}
class U<X, Y, Z> {
    public void hi(X x, Y y) {} //使用類聲明的泛型
}

2.自定義泛型方法

public static void main(String[] args) {
    U<String, Double, Integer> u = new U<>();
    u.m1("xx",22);
    //當調用方法時,傳入參數編譯器會自己確定類型 會自動裝箱
}
class U<X, Y, Z> {
    public <X,Y> void m1(X x,Y y){} //自定義泛型方法
}

這裡的自動裝箱很有意思,他是在三個類型中自動匹配當前輸入的數據類型,也不用考慮順序問題,如圖所示

3.註意事項

①泛型數組不能初始化,因為數組在 new 不能確定A 的類型,就無法在記憶體開空間

錯誤寫法: A[] a=new A[];

②靜態方法不能使用類定義的泛型

原因是靜態成員是和類相關的,在類載入時,對象還沒有創建所以,如果靜態方法和靜態屬性使用了泛型,JVM就無法完成初始化。

來源:iyu77.blog.csdn.net/article/details/125304857

近期熱文推薦:

1.1,000+ 道 Java面試題及答案整理(2022最新版)

2.勁爆!Java 協程要來了。。。

3.Spring Boot 2.x 教程,太全了!

4.別再寫滿屏的爆爆爆炸類了,試試裝飾器模式,這才是優雅的方式!!

5.《Java開發手冊(嵩山版)》最新發佈,速速下載!

覺得不錯,別忘了隨手點贊+轉發哦!


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 1. 關聯關係 1.1 關聯關係概念說明 表與表之間的關係 : 1 對 1 1對多 多對多關係 ,通過主外鍵來實現。 外鍵在多的一方。比如員工和部門: 1個員工對應一個部門,一個部門可以有多個員工 要將表與表之間的關係:映射稱為 類與類之間的關係(準確的說應該是 對象和對象之間的關係 ) 一對一 夫 ...
  • 學習Stream的目的 函數式編程漸漸變成主流,為了看懂同事的代碼。 相對於傳統的編程方式,代碼更為簡潔清晰易懂。 使得併發編程變得如此簡單。 有效的避免了代碼嵌套地獄。(見樣例) if (條件1) { if (條件2) { if (條件3) { // 再嵌套下去都快見到Diablo了。 } } } ...
  • 目錄 一.OpenGL 波浪特效效果演示 1.原始圖片 2.效果演示 二.OpenGL 波浪特效源碼下載 三.猜你喜歡 零基礎 OpenGL ES 學習路線推薦 : OpenGL ES 學習目錄 >> OpenGL ES 基礎 零基礎 OpenGL ES 學習路線推薦 : OpenGL ES 學習目 ...
  • ##redis是什麼? Redis(Remote Dictionary Server ),即遠程字典服務,是一個開源的使用ANSI C語言編寫、支持網路、可基於記憶體亦可持久化的日誌型、Key-Value資料庫,並提供多種語言的API。 redis是一個key-value存儲系統。和Memcached ...
  • Java集合09 18.TreeSet 元素無序:插入順序和輸出順序不一致 可以按照一定的規則進行排序,具體排序方式取決於構造方法: TreeSet () :根據其元素的自然排序進行排序 TreeSet (Comparator comparator) :根據指定的比較器進行排序 沒有帶索引的方法,所 ...
  • 1、獲取bean實例的三種方式 1.1 id 屬性 1.1.1 jar <properties> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> <spring.version>4.3.18.RELEASE</sp ...
  • 最近寫項目發現pythoncom 導入 win32api、win32con、win32com、win32gui 等win32相關的包都會出現或多或少問題,Google一大堆不靠譜的方法試了個遍。 特此記錄一下解決辦法 ...
  • 前言 1,在一些特定的場景我們往往需要看一下介面的入參,特別是跨系統的介面調用(下發,推送),這個時候的介面入參就很重要,我們保存入參入庫,如果出問題就可以馬上定位是上游還是下游的問題(方便扯皮) 2,還有一般需要在系統中看普通日誌,還有特殊的異常(報錯)日誌,一般我們可以通過伺服器去查看相應的位置 ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...