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