泛型 是java中的基礎知識,大家學習java的時候都學習過,平時也經常使用,今天在這裏總結一下泛型。
1.爲什麼我們使用泛型呢?兩種情況:
第一種:
List list = new ArrayList();
list.add("123");
list.add(123);
for (int i = 0; i < list.size(); i++) {
String a = (String) list.get(i);
}
這段代碼,是會報運行時錯誤的。使用泛型,將這種錯誤反應在編譯時。如下:
第二種:
private void equal(String a,String b){
System.out.print(a.equals(b));
}
private void equal(Integer a,Integer b){
System.out.print(a.equals(b));
}
上面這兩個方法,只是參數類型不一樣,實現方式一樣,造成了代碼冗餘。用泛型簡化如下:
private <T> void equal(T a, T b) {
System.out.print(a.equals(b));
}
2.泛型的使用
泛型的一般有三種使用情況:泛型類,泛型接口,泛型方法。
(1)泛型類:
(2)泛型接口:
interface test1<T> {
abstract void aa(T a);
}
(3)泛型方法
注意: 1.第一個不屬於泛型方法,他只是使用了泛型的方法;第二個纔是。
2. 上圖泛型方法的泛型申明和類中一樣,都是T。但是兩個不是一個泛型對象,和形參一樣(局部變量和成員變量名字一 樣時,方法中的該變量和成員變量不是一個)。
3. 泛型的繼承
public class Test1<T extends Node&test1> {
}
如上,我們需要約束泛型使用的時候(比如:希望這個泛型使用只能時Node或者時Node的子類時)我們可以如上約束。
注意:1.約束條件中只能有一個父類約束;
2. 約束條件中可以有無數接口約束;
3. 如果既有父類約束又有接口約束時,父類約束寫第一個。
4. 通配符
public void fanxin() {
//Nodevos 繼承 Node
List<Node> a = new ArrayList<>();
List<Nodevos> b = new ArrayList<>();
setHa(a);
setHa(b);//編譯出錯
}
private void setHa(List<Node> ha) {
return;
}
如上代碼,雖然Nodevos繼承Node,但是List<Node>和List<Nodevos>屬於一個類的對象,不是繼承關係。我們可以驗證一下:
//Nodevos 繼承 Node
List<Node> a = new ArrayList<>();
List<Nodevos> b = new ArrayList<>();
System.out.println(a.getClass());
System.out.print(b.getClass());
這是輸出:
class java.util.ArrayList
class java.util.ArrayList
那這種情況怎麼辦呢?我們使用通配符,代碼如下:
public void fanxin() {
//Nodevos 繼承 Node
List<Node> a = new ArrayList<>();
List<Nodevos> b = new ArrayList<>();
setHa(a);
setHa(b);
}
private void setHa(List<? extends Node> ha) {
return;
}
通配符的兩種情況:
上界通配符 < ? extends E>
下界通配符 < ? super E>
5.小知識:
(1):泛型名稱可以是任意字母,一般大家會選擇一個容易懂的字符:
T:表示一個具體的java類型;
K: key值,V value值;