一、初識泛型
在推出泛型以前,程序員可以創建一個元素類型Object的集合,該集合能夠存儲任意的數據類型對象,而在使用該集合的過程中,需要明確知道存儲每個元素的類型,否則容易引發ClassCastException異常。
泛型是JDK1.5引入的新語法,通俗講,泛型:就是適用于許多許多類型。從代碼講,就是對類型實現了參數化。
JAVA為什么推出泛型?
當Integer類型轉換成String型時,會發生類型轉換錯誤,并且編譯時不會發生錯誤,很容易項目上線時,發生報錯,為了應對這種情況,推出了泛型。
泛型的概念?
Java泛型時JDK5引入的一個新特性,泛型提供了編譯時類型安全監測機制,該機制允許我們編譯時檢測到非法的類型數據結構
泛型的優點?
1.編譯時,類型檢查
2.編譯時,類型轉換
注意:泛型只存在編譯時,運行時不存在泛型這個概念,同時泛型只能接收包裝類型,不能接受普通類型
實現了一類,類中包含了一個數組成員,使得數組中可以存放任何類型的數據,也可以根據成員方法返回數組中某個下標的值
二、泛型類、接口
泛型類的語法
??Generic.java
package demo;
/*
@param<T>泛型標識————類型形參T 創建對象的時候里指定具體的數據類型
*/public class Generic<T>
{private T key;public Generic(T key){this.key = key;}public T getKey() {return key;}public void setKey(T key) {this.key = key;}@Overridepublic String toString() {return "Generic{" +"key=" + key +'}';}
}
??MainClass.java
public class MainClass {public static void main(String[] args) {//泛型類在創建對象的時候,來具體類型Generic<String> strGeneric = new Generic("a");String k1 = strGeneric.getKey();System.out.println(k1);System.out.println("---------------------------------");Generic<Integer> integerGeneric = new Generic<>(123123213);int key2 = integerGeneric.getKey();System.out.println(key2);System.out.println("-------------------------");Generic gen = new Generic();//"當我們不對其使用泛型指定類型時,里面可存儲的值可以為類型類型"}
}f
注意:
泛型不支持基本數據類型,只支持類類型
引用類型無法通過大于和小于進行比較
泛型類型邏輯上可以看作不同類型,實際上都是相同類型
三、泛型的接口
泛型接口的定義語法
Interface 接口名稱<泛型標識,泛型標識,...>{
泛型標識 方法名();
}
實現泛型接口的類,不是泛型類,需要明確實現泛型接口的數據類型。
四、泛型方法
前面我們知道,泛型類,是在實例化類的時候指明泛型的具體類型;而泛型方法,是在調用方法的時候指明泛型的具體類型。
最重要的一點我們之前使用的方法,其實只是實參是泛型參數的普通方法,并不叫做泛型方法。
public class xx<T>
{
private T key;
Public T setKey(T key)
{this.key = key;
}
Public T getKey()
{return key;}
}
定義一個泛型方法需要在返回值前面定義一個<>,里面填入泛型參數,T E ... 等等泛型參數
Public 與返回鍵中間<T>非常重要,可以理解為聲明此方法為泛型方法
只有聲明了<T>的方法才是泛型方法,泛型類中的使用了泛型的成員方法并不是泛型方法。
<T>表明該方法將使用泛型類型T,此時才可以在方法中使用泛型類型T
泛型方法與可變參數
為什么靜態方法訪問不了類上的泛型參數
這是因為,我們在指定泛型參數的具體類型時,是在實例化該類時指定的,實例化后和類型有關,所以靜態方法和靜態屬性訪問 泛型參數,必須在static后添加<T,E......>
五、類型通配符
類型通配符一般是使用”?“代替具體實參類型
所以,類型通配符是類型實參,而不是類型形參。
??Box.java
package Demo01;public class Box<E> {private E first;public E getFirst() {return first;}public void setFirst(E first) {this.first = first;}}
??Test.java
package Demo01;
public class Test {public static void main(String[] args) {Box<Number> box1= new Box<>();box1.setFirst(100);showBox(box1);Box<Integer> box2 = new Box<>();box2.setFirst(200);showBox(box2);}public static void showBox(Box<?> box){Object first = box.getFirst();System.out.println(first);}
}
六、類型擦除
編譯階段,編譯器會進行類型檢測, 一旦通過編譯檢測,進入運行階段,此時泛型這個概念就會消失,通常我們說的,泛型只停留在編譯階段就是這個道理,所有的對象都屬于普通類,所以下面這段代碼的運行結果為true.
類型參數帶來了許多弊端
①、不支持基本類型
②、只有原始類型class
③、不能實例化類型參數
④、不能實例化泛型數組
七、類型的上界
這個地方意味著T必須實現他的上界Comparabe<T>接口
class Alg<T extends Comparable<T>>
{public T findMax(T[] array){T max = array[0];for (int i = 0; i < array.length; i++) {if(max.compareTo(array[i]) < 0){max = array[i];}}return max;}}
public class Test {public static void main(String[] args) {Alg<Integer> alg = new Alg<>();Integer[] array = {1,5,2,7,19,4};Integer max = alg.findMax(array);System.out.println(max);}
}