做3d模型的叫什么牛的網(wǎng)站磁力鏈搜索引擎入口
系列文章目錄
提示:寫完文章后,目錄可以自動生成,如何生成可參考右邊的幫助文檔
文章目錄
- 系列文章目錄
- 前言
- 一、pandas是什么?
- 二、使用步驟
- 1.引入庫
- 2.讀入數(shù)據(jù)
- 總結(jié)
前言
? ? ? ? 學(xué)習(xí)泛型之前請大家先詳細(xì)地了解一下,關(guān)于Java當(dāng)中的包裝類和Object類的概念以及包裝類當(dāng)中的自動裝箱和自動拆箱是什么,如果這部分內(nèi)容不理解的話,泛型當(dāng)中的很多細(xì)節(jié)可能無法理解,這篇文章集中講解泛型當(dāng)中的重難點,對于簡單的細(xì)節(jié)不做介紹。
一、什么是泛型
1、基礎(chǔ)概念
????????泛型是一種在編程語言中實現(xiàn)參數(shù)化類型的機(jī)制,它允許在定義類、接口、方法時使用類型參數(shù),以便在使用時指定具體的類型。Java中引入了泛型的概念,它提供了編譯時的類型檢查,并允許在編寫通用代碼時指定具體的數(shù)據(jù)類型。
2、主要特點
? ? ? ? 1)參數(shù)化類型:泛型允許類、接口、方法在定義時使用參數(shù),這些參數(shù)可以在使用時被具體的類型替代。
? ? ? ? 2)類型安全:泛型提供了編譯時的類型檢查機(jī)制,避免了在運行時出現(xiàn)類型轉(zhuǎn)換異常。這樣,開發(fā)者在編寫代碼時就能發(fā)現(xiàn)并修復(fù)類型相關(guān)的錯誤。
? ? ? ? 3)代碼復(fù)用:泛型增加了代碼的靈活性和復(fù)用性。通用的算法或數(shù)據(jù)結(jié)構(gòu)可以用于處理各種類型的數(shù)據(jù),而不需要為每種類型都編寫相似的代碼。
3、泛型語法
????????在Java中,泛型使用尖括號(<>)來聲明類型參數(shù)。例如:
public class Box<T> {private T value;public Box(T value) {this.value = value;}public T getValue() {return value;} }
????????在上面的例子中,Box 是一個泛型類,其中 表示類型參數(shù)。T 是一個占位符,它會在實例化時被具體的類型替代。
? ? ? ? 使用泛型的例子如下:
// 創(chuàng)建一個存儲整數(shù)的Box對象 Box<Integer> integerBox = new Box<>(42); int intValue = integerBox.getValue(); // 不需要進(jìn)行類型轉(zhuǎn)換,編譯器已經(jīng)檢查過了// 創(chuàng)建一個存儲字符串的Box對象 Box<String> stringBox = new Box<>("Hello, Generics!"); String stringValue = stringBox.getValue(); // 同樣不需要進(jìn)行類型轉(zhuǎn)換
????????在這個例子中,Box 類被實例化兩次,分別用于存儲整數(shù)和字符串,而不需要為每一種類型編寫不同的類。這樣就實現(xiàn)了通用性和代碼復(fù)用。泛型的強(qiáng)大之處在于它可以適用于各種數(shù)據(jù)類型,提高了代碼的靈活性和可維護(hù)性。
?二、為什么需要泛型
1、引出泛型:
????????我們可以通過引入泛型來實現(xiàn)一個通用的類,使其能夠存放任何類型的數(shù)據(jù),并提供方法獲取數(shù)組中指定下標(biāo)的值。以下是一個簡單的示例:
public class GenericArray<T> {private T[] array;// 構(gòu)造方法,初始化泛型數(shù)組public GenericArray(int size) {// 創(chuàng)建泛型數(shù)組的通用方式是使用 Object 類型的數(shù)組,然后進(jìn)行強(qiáng)制類型轉(zhuǎn)換this.array = (T[]) new Object[size];}// 設(shè)置數(shù)組指定下標(biāo)的值public void set(int index, T value) {array[index] = value;}// 獲取數(shù)組指定下標(biāo)的值public T get(int index) {return array[index];}public static void main(String[] args) {// 創(chuàng)建一個存放整數(shù)的數(shù)組GenericArray<Integer> intArray = new GenericArray<>(5);intArray.set(0, 42);intArray.set(1, 15);// 獲取數(shù)組中指定下標(biāo)的值int valueAtIndex1 = intArray.get(1);System.out.println("Value at index 1: " + valueAtIndex1);// 創(chuàng)建一個存放字符串的數(shù)組GenericArray<String> stringArray = new GenericArray<>(3);stringArray.set(0, "Hello");stringArray.set(1, "Generics");// 獲取數(shù)組中指定下標(biāo)的值String valueAtIndex0 = stringArray.get(0);System.out.println("Value at index 0: " + valueAtIndex0);} }
????????在這個示例中,GenericArray 類是一個泛型類,它使用類型參數(shù) T 表示數(shù)組中元素的類型。構(gòu)造方法中創(chuàng)建了一個 Object 類型的數(shù)組,然后進(jìn)行強(qiáng)制類型轉(zhuǎn)換。通過泛型,我們可以在使用該類時指定存放的數(shù)據(jù)類型,從而實現(xiàn)了通用性。
?2、泛型擦除
????????Java中的擦除機(jī)制(Type Erasure)是指在編譯時期,泛型類型信息會被擦除,T這個占位符會被全部替換成為Object或者是它的上界,而在運行時,Java虛擬機(jī)將不再保留泛型類型的具體信息。這是為了向后兼容性,因為在引入泛型之前的Java版本中,是沒有泛型概念的。
? ? ? ? 1)類型參數(shù)擦除:在編譯時,泛型類型的類型參數(shù)將被擦除,替換為Object,例如對于List,編譯后的代碼中的類型信息將被替換為List<Object>。
? ? ? ? 2)泛型數(shù)組限制:由于擦除機(jī)制,不能直接創(chuàng)建泛型數(shù)組。例如,以下代碼是非法的:
List<String>[] arrayOfLists = new ArrayList<String>[10];
????????編譯器會發(fā)出警告,因為在運行時,無法獲得泛型數(shù)組的確切類型信息。通常,可以使用原始類型的數(shù)組,然后進(jìn)行強(qiáng)制類型轉(zhuǎn)換,但這可能導(dǎo)致運行時異常。
擦除機(jī)制的主要目標(biāo)是確保與沒有泛型的舊代碼的兼容性,并允許在運行時處理泛型代碼。然而,擦除也帶來了一些挑戰(zhàn),尤其是在編寫需要在運行時訪問泛型類型信息的代碼時。在這種情況下,通常需要使用反射或其他技術(shù)來處理擦除后的類型。
在Java中,T[] ts = new T[5]; 是不允許的,因為直接創(chuàng)建泛型數(shù)組是違反Java語言規(guī)范的。泛型在Java中是通過擦除實現(xiàn)的,即在運行時泛型信息會被擦除,編譯器會將泛型類型替換為原始類型或其邊界。
T[] ts = new T[5];
????????那么在運行時,它實際上會被替換為:
Object[] ts = new Object[5];
????????這似乎是合理的,但問題在于泛型的目的是提供類型安全性,而直接使用 Object[] 會失去泛型的好處。你可以輕松地將任意對象放入 Object[] 中,而不會得到編譯器的警告。這就違背了使用泛型的初衷,因為泛型的目標(biāo)是在編譯時提供更嚴(yán)格的類型檢查。
因此,為了維護(hù)類型安全性,Java禁止直接創(chuàng)建泛型數(shù)組。相反,你應(yīng)該使用集合類或其他類型安全的數(shù)據(jù)結(jié)構(gòu),或者在需要時使用非泛型數(shù)組,并在運行時進(jìn)行必要的類型轉(zhuǎn)換。
3、為什么不能實例化泛型數(shù)組
? ? ? ? 因為一個T類型的數(shù)組也就是T[] array = new T[];或者:
class MyArray<T> { public T[] array = (T[])new Object[10]; public T getPos(int pos) { return this.array[pos]; } public void setVal(int pos,T val) { this.array[pos] = val; } public T[] getArray() { return array; } } public static void main(String[] args) { MyArray<Integer> myArray1 = new MyArray<>(); Integer[] strings = myArray1.getArray(); }
? ? ? ? 泛型擦除之后,這個泛型又沒有設(shè)置上界(泛型的上界我們一會介紹),T占位符全部被替換成Object,也就是可以是任意類型,這個數(shù)組里面可以存放任意類型,編譯器認(rèn)為這是不安全的,而且數(shù)組存放什么內(nèi)容是運行時決定的,編譯器無法對其進(jìn)行限制,所以Java的編譯器不允許程序員做這樣危險的操作。
? ? ? ? 尤其是這行代碼:
Integer[] strings = myArray1.getArray();
? ? ? ? 這個數(shù)組里面可能存放了任意類型的數(shù)據(jù),而這個時候又要把這個數(shù)組賦值給一個Integer類型的數(shù)組,編譯器一定報錯。
三、泛型上界
????????在定義泛型類時,有時需要對傳入的類型變量做一定的約束,可以通過類型邊界來約束。1、泛型語法????????class 泛型類名稱<類型形參 extends 類型邊界> { ... }
?2、實例
public class MyArray<E extends Number> { ... }
????????只接受 Number 的子類型作為 E 的類型實參MyArray<Integer> l1; // 正常,因為 Integer 是 Number 的子類型 MyArray<String> l2; // 編譯錯誤,因為 String 不是 Number 的子類型
? ? ? ? 如果沒有指定類型邊界 E,可以視為 E extends Object。
四、泛型方法
????????泛型方法是一種在方法級別使用泛型的方式,允許在方法中使用具有獨立類型參數(shù)的泛型。通過泛型方法,我們可以編寫更靈活、通用的代碼,而不受限于整個類的泛型類型參數(shù)。下面是一個簡單的泛型方法的例子:
public class GenericMethodExample {// 泛型方法,接收一個數(shù)組并返回數(shù)組中的最大值//這里是泛型的上界代表著這個方法必須實現(xiàn)Comparable接口public static <T extends Comparable<T>> T findMax(T[] array) {if (array == null || array.length == 0) {return null; // 返回 null 表示數(shù)組為空}T max = array[0];for (T element : array) {if (element.compareTo(max) > 0) {max = element;}}return max;}public static void main(String[] args) {// 使用泛型方法找到整數(shù)數(shù)組的最大值Integer[] intArray = {3, 7, 1, 9, 4};Integer maxInt = findMax(intArray);System.out.println("Max Integer: " + maxInt);// 使用泛型方法找到字符串?dāng)?shù)組的最大值String[] stringArray = {"apple", "orange", "banana", "grape"};String maxString = findMax(stringArray);System.out.println("Max String: " + maxString);} }
????????findMax()方法是一個泛型方法,使用 > 來聲明泛型類型參數(shù)。這表示傳入的類型 T 必須實現(xiàn) Comparable 接口(泛型的上界),以便進(jìn)行比較。
方法使用了泛型類型參數(shù)
????????T 來定義數(shù)組和返回值的類型。這樣,findMax 方法可以接受不同類型的數(shù)組,包括整數(shù)、浮點數(shù)、字符串等。
????????在 main 方法中,我們分別使用 findMax 方法找到整數(shù)數(shù)組和字符串?dāng)?shù)組的最大值。
通過使用泛型方法,我們可以避免為每個類型都編寫一個專門的方法,使代碼更加靈活和通用。泛型方法通常在集合類、算法類等地方得到廣泛應(yīng)用。
?總結(jié)
? ? ? ? 泛型的學(xué)習(xí)主要是為了我們更好地學(xué)習(xí)數(shù)據(jù)結(jié)構(gòu),所以這部分的內(nèi)容大家會用就可以,主要通過上手實踐來解決問題。