99视频精品,69式视频www免费视频,亚洲?成人?综合?另类?小说,最近最新中文字幕完整版免费高清 ,亚洲精品一区二区三区中文字幕

【技術(shù)積累】Java中的泛型【一】

2023-06-11 22:09:30 來源:博客園

泛型是什么

Java中的泛型是一種能夠讓用戶在編寫代碼時避免使用明確的類型而進(jìn)行類型參數(shù)化的機制。Java中的泛型可以讓編程者在代碼編寫時不必關(guān)心具體類型,只用關(guān)心類型之間的關(guān)系和相互轉(zhuǎn)換,從而在編寫代碼的過程中實現(xiàn)類型的復(fù)用。這使得代碼更加簡潔、可讀性更高,并且可以提高代碼的可維護(hù)性和可擴展性。


(相關(guān)資料圖)

Java泛型可以在類、方法、接口、以及數(shù)組等多個地方使用,并且可以結(jié)合約束條件來限制類型參數(shù)的類型。例如,在定義一個泛型類時,可以使用定義一個泛型類型參數(shù),T可以代表任何具體類型,例如Integer、String、Map等。在使用泛型時,可以將具體類型傳遞給類型參數(shù),然后在方法或者類中使用該類型參數(shù),從而實現(xiàn)代碼的類型自動化。

Java中的泛型還具有類型檢查和類型擦除的特性。類型檢查可以檢查在編譯時期是否使用了正確的類型,避免了在運行時期由于類型轉(zhuǎn)換錯誤而產(chǎn)生的異常。而類型擦除則是Java泛型在實現(xiàn)時使用的一種技術(shù),它會去掉泛型中的類型參數(shù)信息,并將其變?yōu)樵碱愋?,在運行時也不會保留泛型的信息,從而實現(xiàn)Java泛型的運行時兼容性。

什么是類型參數(shù)?

Java中的類型參數(shù)是用于泛型編程的占位符,可以用來表示任何類型。它們用尖括號 "<>" 括起來,放置在類名或方法名后面,用來指定通用類型。例如,以下代碼中的 T 就是一個類型參數(shù):
public class MyClass {    private T value;        public void setValue(T value) {        this.value = value;    }        public T getValue() {        return value;    }}
在上面的代碼中,T 代表一個通用類型??梢栽趧?chuàng)建 MyClass 對象時指定 T 的具體類型,如:
MyClass intObj = new MyClass<>();MyClass strObj = new MyClass<>();
這樣,intObj 對象中的 value 的類型就是 Integer,strObj 對象中的 value 的類型就是 String。類型參數(shù)可以用在類、方法、接口等地方,用來實現(xiàn)通用的算法。使用類型參數(shù)可以允許我們編寫一次通用的代碼,可以用于不同類型的數(shù)據(jù),是 Java 泛型編程的核心特性。

什么是類型擦除?

類型擦除(type erasure)是指在Java編譯期間,對泛型類型參數(shù)信息的擦除,將所有泛型類型參數(shù)都用它們的上界(或Object類型)替換,從而在運行時不會保留泛型類型信息。具體來說,編譯器會將泛型類、泛型接口中的類型參數(shù)用對應(yīng)的類型上限(即extends關(guān)鍵字后面的類型)替換,泛型方法中的類型參數(shù)也會被替換。例如,對于以下泛型類:
public class Pair {    private T first;    private S second;    public Pair(T first, S second) {        this.first = first;        this.second = second;    }    public T getFirst() {        return first;    }    public S getSecond() {        return second;    }}
它在編譯后會被轉(zhuǎn)換為:
public class Pair {    private Object first;    private Object second;    public Pair(Object first, Object second) {        this.first = first;        this.second = second;    }    public Object getFirst() {        return first;    }    public Object getSecond() {        return second;    }}
這就是類型擦除的過程,所有泛型類型信息都被擦除并替換為Object類型。雖然泛型類型信息被擦除,但在運行時可以通過反射機制獲取到泛型類型信息,這使得泛型在運行時仍然可以使用。但是,由于類型擦除,泛型類型參數(shù)在運行時無法進(jìn)行類型檢查,因此可能會導(dǎo)致類型安全問題。

什么是通配符類型?

Java中的通配符類型是一種泛型類型,用于表示未知類型的泛型參數(shù)。 通配符類型由問號(?)表示,其可以用作方法的參數(shù)類型、字段類型、局部變量類型等任何地方需要使用泛型類型的地方。

通配符類型有兩種形式:無界通配符類型和有界通配符類型。

無界通配符類型是指使用符號 ? 表示未知類型,例如 List。在使用無界通配符類型時,不能添加任何元素到集合中,因為這個集合的元素類型是未知的。但是,可以從集合中獲取元素,并將其轉(zhuǎn)換為 Object 類型。

有界通配符類型是指使用符號 ? extends 或 ? super,限制泛型參數(shù)的類型范圍。例如,List 表示泛型參數(shù)必須是 Number 類型或其子類型。而 List 表示泛型參數(shù)必須是 Integer 類型或其父類型。在使用有界通配符類型時,可以添加元素到集合中,并能獲取它們。

注意,通配符類型不能用于泛型類或泛型接口的定義,只能作為方法參數(shù)或返回類型的通用形式使用。

什么是泛型方法和泛型類

泛型方法和泛型類是Java中重要的概念,它們的作用是為了提高代碼的可重用性和安全性。

泛型方法是在方法的聲明中使用泛型類型,使得方法可以接受不同類型的參數(shù),同時還可以指定返回值或方法體中使用的泛型類型。泛型方法通常有以下特點:

  1. 泛型方法可以在方法中定義自己的類型參數(shù),也可以使用類定義的類型參數(shù)。
  2. 泛型方法可以接受任意類型的參數(shù),即可以接受參數(shù)化類型,也可以接受普通類型。
  3. 泛型方法可以有多個類型參數(shù),也可以沒有類型參數(shù)。
  4. 泛型方法可以有泛型類型的返回值。

下面是一個使用泛型方法的例子:

public static  void printArray(T[] array) {    for (int i = 0; i < array.length; i++) {        System.out.print(array[i] + " ");    }    System.out.println();}

在這個例子中,我們定義了一個名為 printArray 的泛型方法,它接受一個泛型數(shù)組作為參數(shù),并且使用 for 循環(huán)遍歷數(shù)組的每個元素,最后輸出所有元素到控制臺。

泛型類是在類的聲明中使用泛型類型,使得類可以接受不同類型的參數(shù),同時還可以指定類中使用的泛型類型。泛型類通常有以下特點:

  1. 泛型類可以在類名后面添加泛型類型參數(shù)。
  2. 泛型類可以在類中定義泛型類型的實例變量。
  3. 泛型類可以有泛型類型的構(gòu)造方法。
  4. 泛型類可以有泛型類型的方法。

下面是一個使用泛型類的例子:

public class Box {    private T value;    public Box(T value) {        this.value = value;    }    public T getValue() {        return value;    }    public void setValue(T value) {        this.value = value;    }    public static void main(String[] args) {        Box box = new Box<>(10);        System.out.println(box.getValue());    }}

在這個例子中,我們定義了一個名為 Box 的泛型類,它有一個泛型類型參數(shù) T,同時定義了一個名為 value 的實例變量,以及相應(yīng)的 get 和 set 方法。在 main 方法中,我們創(chuàng)建了一個 Box 對象,并且使用泛型類型為 Integer 的參數(shù),然后輸出了這個對象的值到控制臺。

總的來說,泛型方法和泛型類是Java中非常重要的概念,它們可以為我們提供更加靈活和安全的編程方式,同時也是提高代碼可讀性和可維護(hù)性的有效手段。

泛型類中是否可以繼承泛型類

Java中泛型類可以繼承泛型類,這一特性被稱為泛型的繼承或泛型的子類化。

在泛型類繼承中,子類繼承的父類可以是泛型類也可以是非泛型類。當(dāng)子類繼承的父類是泛型類時,子類可以繼承父類的泛型類型;也可以在繼承時指定自己的泛型類型。

下面是一個范例來展示Java中泛型類繼承泛型類的用法:

public class Parent {    // 泛型類型 T    private T data;    public void setData(T data) {        this.data = data;    }    public T getData() {        return data;    }}public class Child extends Parent {    // 繼承泛型類 Parent}public class Test {    public static void main(String[] args) {        Child child = new Child(); // 子類指定了泛型類型為 String        child.setData("Hello World");        System.out.println(child.getData()); // 輸出結(jié)果為 "Hello World"    }}

在上面的例子中,Child類繼承了Parent類,由于Parent類是一個泛型類,所以Child類又繼承了Parent類的泛型類型T。而在定義Child類時,也可以在繼承Parent類時指定T的具體類型,如Child,從而使Child類也成為具有泛型特性的類。

總結(jié)一下,Java中允許泛型類繼承泛型類,子類也可以使用父類的泛型類型或為自己指定泛型類型。這個特性可以幫助開發(fā)者更好地管理和組織泛型類,能夠提升代碼的可重用性和可讀性。

泛型方法中是否可以聲明泛型類

Java中泛型方法可以聲明泛型類,這樣可以在方法中使用泛型類型參數(shù),從而在方法中實現(xiàn)通用的操作。

除了聲明泛型類,泛型方法還可以聲明泛型方法參數(shù)、返回類型,以及利用泛型通配符進(jìn)行類型轉(zhuǎn)換等常用操作。

以下是一個簡單的示例,展示了在泛型方法中聲明泛型類的用法:

public class MyClass {    public  void printElements(E[] elements) {        for (E element : elements) {            System.out.println(element.toString());        }        T obj = new T();  // 泛型類類型參數(shù)T在泛型方法中使用    }}public class Test {    public static void main(String[] args) {        Integer[] integers = {1, 2, 3, 4, 5};        String[] strings = {"Hello", "World"};        MyClass myClass = new MyClass<>();        myClass.printElements(integers);        MyClass myClass1 = new MyClass<>();        myClass1.printElements(strings);    }}

在上述代碼中,我們定義了一個泛型類 MyClass,其中,又定義了一個名為 printElements 的泛型方法,該方法中使用了泛型類型參數(shù) E[],并在方法中對數(shù)組元素進(jìn)行遍歷輸出;同時,方法中也使用了泛型類型參數(shù) T,在方法中初始化一個泛型類類型參數(shù)T的對象。

在Test類中,我們實例化了兩個 MyClass 類,分別強制指定泛型類型參數(shù)為 Integer 類型和 String 類型,并通過執(zhí)行各自的 printElements 方法來打印數(shù)組元素。

通過這種方式,Java中的泛型方法不僅支持泛型類型參數(shù),也支持對泛型類(包括實例化泛型類對象)的操作,從而讓我們可以實現(xiàn)更加通用的方法封裝,提升代碼的可讀性和復(fù)用性。

為什么類型參數(shù)不能是原始類型

  1. 泛型的類型擦除機制

Java中的泛型是通過類型擦除機制實現(xiàn)的。泛型類和方法會在編譯時通過擦除類型信息來去除泛型的影響,轉(zhuǎn)換成原始類型。例如,List和List在編譯后都會變成List

原始類型與泛型類無法一起使用,這樣會破壞Java 的類型安全。如果類型參數(shù)允許原始類型,那么在擦除類型信息之后,無法在運行時獲得類型信息,這就導(dǎo)致了無法編寫通用的泛型代碼。

  1. 原始類型的限制

原始類型不能繼承任何類,也無法實現(xiàn)任何接口。如果類型參數(shù)可以是原始類型,那么泛型類就無法利用Java強大的面向?qū)ο筇匦詠韺崿F(xiàn)更加復(fù)雜、靈活的結(jié)構(gòu)。

  1. 自動類型轉(zhuǎn)換問題

Java中自動類型轉(zhuǎn)換和類型擦除機制可能會導(dǎo)致類型參數(shù)變?yōu)樵碱愋?。例如,我們在泛型方法中將一個原始類型轉(zhuǎn)換為一個泛型類型參數(shù),當(dāng)運行時擦除類型時,這個泛型類型變成了Object類型,而不是我們想要的類型參數(shù)。

綜上所述,Java中為什么類型參數(shù)不能是原始類型,是因為這種做法會破壞Java的類型安全和面向?qū)ο筇匦?,無法實現(xiàn)通用的泛型代碼。

什么是限定通配符和無限定通配符?

限定通配符是Java中泛型的一個重要特性,用于指定泛型參數(shù)的上界或下界。

在Java中,泛型參數(shù)不僅可以指定具體的類型,還可以指定一個范圍,即可以定義類型的上界或下界。限定通配符就是用來指定這個范圍的符號。

限定通配符分為extends和super兩種類型:

  1. extends限定通配符:用于指定泛型參數(shù)的上界。表示類型必須是指定類型或其子類。

示例:List 表示泛型參數(shù)必須是Number或其子類,如Integer、Double等。

  1. super限定通配符:用于指定泛型參數(shù)的下界。表示類型必須是指定類型或其父類。

示例:List 表示泛型參數(shù)必須是Integer或其父類,如Number、Object等。

限定通配符的作用是確保泛型參數(shù)的類型符合特定的條件,同時增加代碼的可用性和可讀性。

Java中的無限定通配符(Unbounded Wildcard)是指泛型參數(shù)沒有任何限制,使用符號"?"來表示。

示例:List 表示List中可以存放任何類型的對象,相當(dāng)于是List的簡化寫法。

無限定通配符可以用于以下情況:

  1. 當(dāng)泛型參數(shù)類型并不重要時,比如在方法中只需要對泛型參數(shù)進(jìn)行處理而不需要知道具體類型。

  2. 當(dāng)泛型類型的上界或下界無法確定時,比如在方法中需要接受不同類型的List對象,但是這些List對象的元素類型并不確定。

無限定通配符并不能直接調(diào)用參數(shù)的方法或者添加新的元素,因為其具體的類型是未知的,需要通過強制類型轉(zhuǎn)換才能進(jìn)行操作。

什么是類型邊界

Java泛型中的類型邊界(Type Bound)是指限制泛型類型參數(shù)的范圍,使得參數(shù)只能是特定類或其子類,或者實現(xiàn)了特定接口的類或其實現(xiàn)類。

類型邊界有兩種形式:extends和super。extends用于限制類型參數(shù)的上界(Upper Bound),即指定參數(shù)只能是某一類或其子類的類型;super用于限制類型參數(shù)的下界(Lower Bound),即指定參數(shù)只能是某一類或其父類的類型。

//類型邊界為Number及其子類public class GenericClass {private T number;public GenericClass(T number) {this.number = number;}public T getNumber() {return number;}}GenericClass intClass = new GenericClass<>(10);GenericClass doubleClass = new GenericClass<>(3.14);//類型邊界為String及其父類public class GenericClass {private T str;public GenericClass(T str) {this.str = str;}public T getString() {return str;}}GenericClass objClass = new GenericClass<>("Hello World");GenericClass charSeqClass = new GenericClass<>("Hello World");

什么是協(xié)變

Java泛型中的協(xié)變(Covariant)是指泛型類型參數(shù)的子類型關(guān)系能夠被繼承到泛型類的實例化類型中。也就是說,子類型的泛型類實例可以替代父類型的泛型類實例。

在Java中,協(xié)變類型只有在泛型參數(shù)是用作方法返回值類型時才可以生效。在這種情況下,如果泛型實例可以返回子類型對象,則該類型為協(xié)變類型。

public class Animal {}public class Dog extends Animal {}//泛型協(xié)變public class GenericClass {public T getAnimal() {return null;}}GenericClass dogClass = new GenericClass<>();GenericClass animalClass = dogClass;Animal animal = animalClass.getAnimal(); //協(xié)變成Animal類型Dog dog = dogClass.getAnimal(); //無需轉(zhuǎn)換,返回類型為Dog

什么是類型變量的繼承

Java泛型中,類型變量的繼承是指當(dāng)一個泛型類型參數(shù)被聲明在一個類中,并被另一個類繼承時,繼承后的子類可以直接使用該泛型類型參數(shù)。

具體來說,當(dāng)一個類聲明了泛型類型參數(shù)T,在另一個類中繼承該類時,可以通過在子類中指定T的具體類型來使用其父類中聲明的泛型類型。子類可以繼承和使用其父類中的泛型類型,或者在實現(xiàn)接口時使用泛型類型。

public class ParentClass {T t;public T getT() {return t;}}public class ChildClass extends ParentClass {}ChildClass child = new ChildClass<>();child.setT("Hello"); //繼承父類中的泛型類型TString s = child.getT(); //繼承父類中的泛型類型T//類實現(xiàn)接口時使用泛型類型public interface MyInterface {public T getT();}public class MyClass implements MyInterface {}MyClass myClass = new MyClass<>();String s = myClass.getT(); //使用泛型類型T

關(guān)鍵詞:

相關(guān)新聞