1. 程式人生 > >Java學習筆記——泛型

Java學習筆記——泛型

ray dem 想想 string stub odt 好處 reac test

一、什麽是泛型?為什麽要使用泛型?

且看代碼:

 1 public class GenericsDemo {
 2 
 3     public static void main(String[] args) {
 4         List list = new ArrayList<>();
 5         list.add("1");
 6         list.add("2");
 7         list.add("3");
 8         list.add(5);//不小心把Integer丟進了集合中
 9         //編譯不報錯,運行時發生java.lang.ClassCastException異常
10 list.forEach(str -> System.out.println((String)str)); 11 } 12 }

第8行代碼不小心把Integer丟了進去,會引發ClassCastException

使用了泛型後:

 1 public class GenericsDemo {
 2 
 3     public static void main(String[] args) {
 4         
 5         List<String> list = new ArrayList<>();
 6         list.add("
1"); 7 list.add("2"); 8 list.add(3);//不小心把Integer丟進了集合中,編譯報錯 9 } 10 }

第一段代碼可能引發運行時異常ClassCastException的代碼,在上面代碼中直接編譯報錯了。

 1 public class GenericsDemo {
 2 
 3     public static void main(String[] args) {
 4         
 5         List<String> list = new ArrayList<>();
6 list.add("1"); 7 list.add("2"); 8 list.add("3"); 9 list.add("4"); 10 list.forEach(str -> System.out.print(str)); 11 } 12 }

發現了麽,第10行不用吧str強制轉換為String類型了。

1 public class GenericsDemo {
2 
3     public static void main(String[] args) {
4         Object o = new Integer(10);
5         Float f = (Float)o;
6     }
7 }

程序在編譯時並不知道你到底傳了什麽類型的變量。由於多態(想想貓和狗的例子),程序運行的的時候可能發生類型轉換異常。

為了避免ClassCastException運行時異常,Java引入泛型機制。

使用泛型的好處:

1、避免了ClassCastException

2、免去了大量的強制轉換

二、定義泛型類和泛型接口

上代碼:

使用泛型定義類(泛型定義接口的道理是一樣的)

 1 public class Bag <T>{
 2 
 3     private T content;
 4 
 5     Bag(T content) {
 6         this.content = content;
 7     }
 8 
 9     T getContent() {
10         return content;
11     }
12 
13     void setContent(T content) {
14         this.content = content;
15     }
16 }

這裏想下普通的定義方法,T是特定的類型(比如String)。這裏的T可以是任意類型,類型範圍很廣。

1 public class TestBag {
2 
3     public static void main(String[] args) {
4         Bag<String> bag = new Bag<String>("book");
5         Integer cintent = bag.getContent();//編譯出錯
6         String content1 = bag.getContent();
7     }
8 }

三、使用extends關鍵字限定類型參數

上代碼:

 1 public class LimitBag <T extends Number>{
 2 
 3     private T content;
 4 
 5     LimitBag(T content) {
 6         this.content = content;
 7     }
 8 
 9     T getContent() {
10         return content;
11     }
12 
13     void setContent(T content) {
14         this.content = content;
15     }
16 }
1 public class TestBag {
2 
3     public static void main(String[] args) {
4     
5         LimitBag<String> bag = new LimitBag<String>("book");//編譯出錯
6         LimitBag<Integer> bag2 = new LimitBag<Integer>(1);//合法
7     }
8 }

四、定義泛型數組

上代碼:

 1 public class GenericArray<T> {
 2 
 3     private T[] content;
 4 
 5     GenericArray(T[] content) {
 6         this.content = content;
 7     }
 8 
 9     T[] getContent() {
10         return content;
11     }
12 
13     void setContent(T[] content) {
14         this.content = content;
15     }
16     
17 }

 1 public class TestBag {
 2 
 3     public static void main(String[] args) {
 4                 
 5         String[] content = {"1","2","3"};
 6         GenericArray<String> ss= new GenericArray<>(content);
 7         for (String item : ss.getContent()) {
 8             System.out.println(item);
 9         }
10     }
11 }

五、定義泛型方法

上代碼:

 1 public class MethodTest {
 2 
 3     public static <E> void printArray(E[] arr){
 4         for (E item : arr) {
 5             System.out.println(item);
 6         }
 7     }
 8     public static <T extends Comparable<T>> T max(T x,T y){
 9         return x.compareTo(y)>0?x:y;
10     }
11     public static void main(String[] args) {
12         Integer[] arr = {1,2,3};//必須是包裝類
13         printArray(arr);
14         System.out.println(max("B", "a"));
15     }
16     
17 }

六、問號通配符

上代碼

1 public class WildCast {
2 
3     public static void main(String[] args) {
4         Set<String> set = new HashSet<String>();//向上轉型
5         //HashSet<Object> set = new HashSet<String>();//編譯出錯Type mismatch,泛型Object和泛型String之間不存在繼承關系
6     }
7 }

在看下面代碼:

 1 public class WildCast {
 2 
 3     public static void main(String[] args) {
 4         
 5         List<Integer> list = new ArrayList<>();
 6         list.add(11);
 7         print(list);//編譯出錯
 8         printNew(list);
 9     }
10 
11     private static void printNew(Collection<?> collection) {
12         // TODO Auto-generated method stub
13         collection.forEach(obj -> System.out.println(obj));
14     }
15 
16     private static void print(Collection<Object> collection) {
17         // TODO Auto-generated method stub
18         collection.forEach(obj -> System.out.println(obj));
19     }
20 }

泛型<Integer>和泛型<Object>沒有繼承關系,不能傳遞。所以使用通配符<?>

Java學習筆記——泛型