成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

探秘 Java 泛型:從類型參數到邊界限制與類型擦除

開發
本文深入探討了 Java 中的泛型概念及其使用方法,并給出了多個基本示例。理解和運用泛型能增強程序類型安全性,消除顯式強制轉換需求,使代碼更具重用性和可維護性。

在 Java 編程中,大家或許都遭遇過令人頭疼的ClassCastException,尤其是在處理如Integer、String等不同類型對象時。這個異常通常是由于將對象強制轉換為錯誤的數據類型所導致的。不過,Java 中的泛型可以幫助我們解決這一問題。

為什么我們需要泛型?

讓我們從一個簡單的例子開始。我們首先將不同類型的對象添加到一個ArrayList中。然后打印它們的值。

List list = new ArrayList();
list.add("Hello");
String str = (String) list.get(0);
System.out.println("String: " + str);

這里,我們向ArrayList添加了一個String對象。由于代碼是自己編寫,我們清楚元素類型,但編譯器并不知曉。所以從列表獲取值時得到的是Object類型,必須進行顯式強制轉換。

list.add(123);
String number = (String) list.get(1);
System.out.println("Number: " + number);

如果我們向這個列表中添加一個Integer并嘗試獲取該值,我們將得到一個ClassCastException,因為Integer對象不能被強制轉換為String。 而使用泛型,就能解決上述兩個問題。使用菱形運算符明確指定列表中保存的對象類型,可實現編譯時檢查,無需顯式強制轉換。

List<String> list = new ArrayList<>();
list.add("Hello");
String str = list.get(0); // 無需顯式強制轉換
System.out.println("String: " + str);
list.add(123); // 拋出編譯時錯誤

類型參數命名約定

在前面示例中,List<String>的使用限制了列表可保存的對象類型。再看Box類處理不同類型數據的示例:

public class Box<T> {
    private T value;

    public void setValue(T value) {
        this.value = value;
    }

    public T getValue() {
        return value;
    }

    public static void main(String[] args) {
        Box<String> stringBox = new Box<>();
        stringBox.setValue("Hello, world!");
        System.out.println(stringBox.getValue());

        Box<Integer> integerBox = new Box<>();
        integerBox.setValue(123);
        System.out.println(integerBox.getValue());
    }
}

注意Box<T>類的聲明,這里T是類型參數,表示Box類可處理該類型的任意對象。在main方法中創建Box<String>和Box<Integer>實例,確保了類型安全。

根據官方文檔,類型參數名稱通常為單個大寫字母。常見的類型參數名稱有:

  • E - 元素(廣泛用于 Java 集合框架)
  • K - 鍵
  • N - 數字
  • T - 類型
  • V - 值
  • S、U、V等 - 第二、第三、第四種類型

讓我們看看如何編寫一個泛型方法:

public static <T> void printArray(T[] inputArr) {
    for (T element : inputArr) {
        System.out.print(element + " ");
    }
    System.out.println();
}

這里,我們接受任何類型的數組并打印其元素。請注意,你需要在方法返回類型之前的尖括號<>中指定泛型類型參數T。方法體遍歷我們作為參數傳遞的任何類型T的數組,并打印每個元素。

public static void main(String[] args) {
    // 創建不同類型的數組(Integer、Double和Character)
    Integer[] intArr = {1, 2, 3, 4, 5};
    Double[] doubleArr = {1.1, 2.2, 3.3, 4.4, 5.5};
    Character[] charArr = {'H', 'E', 'L', 'L', 'O'};

    System.out.println("Integer數組包含:");
    printArray(intArr);   // 傳遞一個Integer數組

    System.out.println("Double數組包含:");
    printArray(doubleArr);   // 傳遞一個Double數組

    System.out.println("Character數組包含:");
    printArray(charArr);   // 傳遞一個Character數組
}

我們可以通過傳遞不同類型的數組(Integer、Double、Character)來調用這個泛型方法,你會看到你的程序將打印出這些數組的每個元素。

泛型的限制

在泛型中,我們使用邊界來限制泛型類、接口或方法可以接受的類型。有兩種類型:

1. 上界

這用于將泛型類型限制為上限。要定義上界,你使用extends關鍵字。通過指定上界,你確保類、接口或方法接受指定的類型及其所有子類。 語法如下:<T extends SuperClass>。例如,修改Box類:

class Box<T extends Number> {
    private T value;

    public void setValue(T value) {
        this.value = value;
    }

    public T getValue() {
        return value;
    }
}

在這個例子中,T可以是任何擴展Number的類型,如Integer、Double或Float。

2. 下界

這用于將泛型類型限制為下限。要定義下界,你使用super關鍵字。通過指定下界,你確保類、接口或方法接受指定的類型及其所有超類。 語法如下:<T super SubClass>。以下是使用下界的示例:

public static void printList(List<? super Integer> list) {
    for (Object element : list) {
        System.out.print(element + " ");
    }
    System.out.println();
}

下界<? super Integer>的使用確保你可以將指定的類型及其所有超類(在這種情況下是Integer、Number或Object的列表)傳遞給printList方法。

什么是通配符?

你在上一個示例中看到的?被稱為通配符。你可以使用它們來引用未知類型。你可以使用帶有上界的通配符,在這種情況下它看起來像這樣:<? extends Number>。它也可以與下界一起使用,如<? super Integer>。

類型擦除

我們在類、接口或方法中使用的泛型類型僅在編譯時可用,并且在運行時會被刪除。這樣做是為了確保向后兼容性,因為舊版本的Java(Java 1.5之前)不支持它。 編譯器利用泛型類型信息確保類型安全。類型擦除過程如下:

  • 對于有界泛型類型,編譯器會將其擦除為它的上界類型。例如,class Box<T extends Number>,T會被擦除為Number。
  • 對于無界泛型類型(如class Box<T>),T會被擦除為Object。所以在運行時,實際上并不能獲取到泛型參數的具體類型信息。
import java.util.ArrayList;
import java.util.List;
class GenericExample<T> {
    private List<T> list = new ArrayList<>();
    public void add(T element) {
        list.add(element);
    }
    public T get(int index) {
        return list.get(index);
    }
}

當編譯器編譯這段代碼時,T會被擦除。對于add方法,實際上變成了類似public void add(Object element)(如果T是無界的)。對于get方法,返回值類型也被擦除為Object,不過編譯器會在需要的時候插入強制類型轉換。

結論

本文深入探討了 Java 中的泛型概念及其使用方法,并給出了多個基本示例。理解和運用泛型能增強程序類型安全性,消除顯式強制轉換需求,使代碼更具重用性和可維護性。希望通過本文的介紹,大家能在 Java 編程中更好地運用泛型,提升代碼質量。

責任編輯:趙寧寧 來源: 程序猿技術充電站
相關推薦

2023-03-24 15:53:24

JavaJava 泛型開發

2024-06-07 10:05:31

2023-04-10 16:34:45

編程Java開發

2011-04-13 09:16:55

泛型

2009-08-24 14:51:25

C# 泛型泛型類型

2021-08-24 08:05:41

泛型類型擦除Class

2022-03-02 14:41:03

泛型反序列化

2025-05-30 02:31:00

2025-03-26 01:45:00

泛型C#開發者

2020-12-21 16:18:07

JavaTypeToken泛型擦除

2009-09-08 16:36:10

LINQ查詢基于泛型類

2022-06-19 22:54:08

TypeScript泛型工具

2009-04-24 09:33:12

LINQ查詢非泛型

2021-07-01 06:47:30

Java泛型泛型擦除

2023-03-06 08:33:24

IDEA反編譯類型

2009-08-24 14:20:13

C# 強制類型轉換

2024-03-06 08:17:18

Java泛型安全

2024-11-05 09:11:09

TypeScript開發者代碼

2013-03-20 09:27:33

C#泛型

2021-07-29 09:20:18

Java泛型String
點贊
收藏

51CTO技術棧公眾號

主站蜘蛛池模板: 国产成人综合在线 | 美日韩免费 | 国产精品久久久久无码av | 日韩免费毛片视频 | 三区在线 | 久久久久久色 | 爱爱综合网| 日韩一区二区三区视频 | 日日欧美 | 午夜影院在线观看免费 | 亚洲天堂久久 | 国产一区二区在线播放 | 亚洲一区影院 | 九九伦理电影 | 欧美二区乱c黑人 | 日韩高清一区二区 | 男人电影天堂 | 一区观看 | 日本不卡视频在线播放 | 婷婷精品 | 中文字幕亚洲区一区二 | 激情五月激情综合网 | 在线视频中文字幕 | 精品国产一区二区在线 | 亚洲精品乱码久久久久久蜜桃91 | 欧美日本一区 | 亚洲国产精品精华素 | 超碰日本 | 久久91| 欧美精品中文 | 色播av| 国产一区二区三区 | 天天综合网天天综合色 | 欧美一区二区三区大片 | 欧美一级片中文字幕 | 国产精品伦理一区二区三区 | 米奇7777狠狠狠狠视频 | 亚洲精品白浆高清久久久久久 | 久久久激情视频 | 午夜视频一区二区三区 | 成人亚洲精品 |