泛型是什麼?
泛型是什麼呢?從字面意思來理解就是廣泛的類型(個人理解)。泛型是 jdk1.5 的產物,被業界大佬稱之爲 jdk 的里程碑事件。到底是什麼原因使得這樣的產物讓廣大 Java 程序員讚不絕口。聽我細細侃來。
引出泛型:
每件事物的產生必然有一定的道理,泛型亦是如此。
我們來看一下下面這個集合:
public class Ttest01 {
public static void main(String[] args) {
MySet set = new MySet();
// 向集合中添加一個字符串
set.add("abc");
String info = (String) set.get(0);
System.out.println(info);
// 向集合中添加一個整數
set.add(2);
// 插入一個整數,取的時候除了我們自己沒有人知道插入的類型是什麼
// 究竟強轉成什麼,不同的用戶有不同的選擇
String info1 = (String) set.get(1);
System.out.println(info1);
}
}
// 集合類
class MySet{
Object[] mySet = new Object[10];
int idx = 0;
// 向集合中插入一個元素
public void add(Object value) {
mySet[idx ++] = value;
}
// 獲取元素的值
public Object get(int idx) {
return mySet[idx];
}
}
通過上面的樣例,代碼在編寫的過程中是不會報錯的,但是在實際運行過程中呢?
顯然代碼報錯了。
先不說代碼有錯的問題,假設給你一個這樣的集合,咱不知道集合中每個元素的數據類型,咱是不是要一個一個進行強制轉換呢?而且我們也不知道究竟應該轉成哪種類型纔不會報錯。(我要是項目經理,估計就被氣死了)
泛型應運而生:
既然一個集合中有String類型,有 Integer 類型,那麼我們能不能一個集合中只存儲 String ,一個集合只存 Integer 類型呢?顯然是可以的。
看代碼:
public class Ttest01 {
public static void main(String[] args) {
MySet1 set = new MySet1();
set.add("abc");
String info = (String) set.get(0);
System.out.println(info);
}
}
class MySet1{
String[] mySet = new String[10];
int idx = 0;
public void add(String value) {
mySet[idx ++] = value;
}
public String get(int idx) {
return mySet[idx];
}
}
當我們規定這個集合中只能存 String 類型時,那麼我們想插入一個 Integer 類型的數據時會出現什麼情況呢?
紅線警告了,說明我們只能向集合中插入 String 類型。
當指定集合中的具體類型有什麼好處呢?
1、給予每個使用該集合的用戶 明確的信息。
2、如果插入不同的數據類型會進行錯誤提示。
3、不再需要進行不確定的強制類型轉換。
可能有的小夥伴會想,我們原來的集合既可以存儲String類型的,又可以存儲 Integer 類型的,這樣不好嗎?
別慌,相信現在你已經明白一點,原來的方式取出時是不方便的,並且對於一個不知道你的集合中各個元素的數據類型的用戶來說,使用起來是及其不方便的。
還有一點,在後面會提到。
泛型推導:
說了這麼多廢話,終於到Boss出場了。
當我們想讓一個集合中都是 Integer 類型會怎麼做呢?
class MySet2{
Integer[] mySet = new Integer[10];
int idx = 0;
public void add(Integer value) {
mySet[idx ++] = value;
}
public Integer get(int idx) {
return mySet[idx];
}
}
我們上面的 String 類型是什麼樣的呢?
class MySet1{
String[] mySet = new String[10];
int idx = 0;
public void add(String value) {
mySet[idx ++] = value;
}
public Object get(int idx) {
return mySet[idx];
}
}
仔細觀察一下就會發現,這兩個類型裏面有很多重複的代碼,如果說 之後還會有 Double,Person、Dog 類型的,我們是不是要寫更多的代碼呢?瞭解 Java 的都
多少知道一點,就是代碼的複用。
class MySet1{
X[] mySet = new X[10];
int idx = 0;
public void add(X value) {
mySet[idx ++] = value;
}
public X get(int idx) {
return mySet[idx];
}
}
看這個代碼,我們將兩份代碼中不同的部分用 X 替換掉,每次只調用這個是不是就 OK 了。
那麼如何傳遞這個 X 呢?
class MySet1<X>{
X[] mySet = new X[10];
int idx = 0;
public void add(X value) {
mySet[idx ++] = value;
}
public X get(int idx) {
return mySet[idx];
}
}
上面的方式是不健全的,說白了就是有問題的,在泛型類中是不可以直接 new X[10] 的,具體就不再詳細說了(原諒博主的尷尬,下面的例子效果是一樣的,具體看下面的例子吧)。
所以不得不通過另一個例子來說明問題了,實際上只要知道 X 是怎麼推出來的就行了。
通過下面的例子我們看一下如何調用:
import org.omg.CORBA.Object;
import java.util.Arrays;
public class Ttest01 {
public static void main(String[] args) {
MySet1<String> set = new MySet1<String>();
set.add("a");
System.out.println(set.get());
}
}
// 給予類一個放參數的位置
class MySet1<E>{
private E value;
public void add(E value) {
this.value = value;
}
public E get() {
return value;
}
}
像方法一樣 加個參數就可以啦。
想讓集合中都是 Integer 類型怎麼辦呢?
MySet1<Integer> set = new MySet1<Integer>();
所以根據需要修改不同的參數即可。
如果想集合中既有String又有Interger 呢?
MySet1 set = new MySet1();
看下完整代碼:
import org.omg.CORBA.Object;
import java.util.Arrays;
public class Ttest01 {
public static void main(String[] args) {
MySet1 set = new MySet1();
set.add("a");
set.add("123");
System.out.println(set.get());
}
}
class MySet1<E>{
private E value;
public void add(E value) {
this.value = value;
}
public E get() {
return value;
}
}
是沒問題的,運行結果也是沒問題的,可以自己嘗試一下。
所以說,泛型是原先集合的加強,在原來的基礎上進去強化。
類是對象的模板,泛型是類的模板
這句話通過上面的例子可以好好琢磨一下,根據泛型我們可以創建的不同的類,
MySet1< Integer >
MySet1< String >
仔細看看確實蠻有道理的,嘻嘻。
泛型好在哪裏?
下面是我從某個地方的論壇上看到的,感謝大佬,引用一下:
Java語言引入泛型的好處是安全簡單。泛型的好處是在編譯的時候檢查類型安全,並且所有的強制轉換都是自動和隱式的,提高代碼的重用率。
1,類型安全。 泛型的主要目標是提高 Java
程序的類型安全。通過知道使用泛型定義的變量的類型限制,編譯器可以在一個高得多的程度上驗證類型假設。沒有泛型,這些假設就只存在於程序員的頭腦中(或者如果幸運的話,還存在於代碼註釋中)。2,消除強制類型轉換。 泛型的一個附帶好處是,消除源代碼中的許多強制類型轉換。這使得代碼更加可讀,並且減少了出錯機會。
3,潛在的性能收益。
泛型爲較大的優化帶來可能。在泛型的初始實現中,編譯器將強制類型轉換(沒有泛型的話,程序員會指定這些強制類型轉換)插入生成的字節碼中。但是更多類型信息可用於編譯器這一事實,爲未來版本的
JVM 的優化帶來可能。由於泛型的實現方式,支持泛型(幾乎)不需要 JVM
或類文件更改。所有工作都在編譯器中完成,編譯器生成類似於沒有泛型(和強制類型轉換)時所寫的代碼,只是更能確保類型安全而已。
後記:
基本就介紹完了,中間有點小尷尬,不過相信正在看的你一定可以理解的,如果有疑問的可以隨時問我,相互學習,共同進步。
如果感覺對您有幫助,點個贊,點個關注哦,感謝感謝。
加油!少年!