Java學習筆記——泛型
阿新 • • 發佈:2017-05-12
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學習筆記——泛型