所謂泛型就是允許在定義類、接口時指定類型形參,這個類型形參將在聲明變量、創建對象時確定。增加了泛型支持后的集合,完全可以記住集合
中元素的類型,並可以在編譯時檢查集合中元素的類型。即解決一些安全問題,同時還可以讓代碼變得更加簡潔。
一、使用泛型
泛型的格式:通過<>來定義要操作的引用數據類型
創建一個只存放字符串的對象,代碼如下:
package com.csu.test1; import java.util.ArrayList; import java.util.List; public class GenericDemo { public static void main(String[] args) { //創建一個只能保存字符串的ArrayList集合 List<String> strList=new ArrayList<String>(); //如果存放其他類型的對象時會出現編譯錯誤 strList.add("chaofn"); System.out.println(strList); } }
使用泛型的好處:
1、將運行時期出現的ClassCastExcpetion , 轉移到了編譯時期。方便於程序員解決問題,讓運行時期問題減少。
2、避免了強制轉換的麻煩。
如下代碼可以解釋這一點:
package com.csu.test1; import java.util.ArrayList; import java.util.Iterator; import java.util.List; class StringDemo { String name; public StringDemo(String name){ this.name=name; } } public class GenericDemo { public static void main(String[] args) { //創建一個只能保存字符串的ArrayList集合 List ls=new ArrayList(); //如果存放其他類型的對象時會出現編譯錯誤 ls.add(new StringDemo("chaofn01")); ls.add(new StringDemo("chaofn02")); ls.add(new StringDemo("chaofn03")); ls.add(new StringDemo("chaofn04")); ls.add(1000); MyIterator(ls); } public static void MyIterator(List ls){ Iterator it=ls.iterator(); while(it.hasNext()){ StringDemo s=(StringDemo) it.next(); System.out.println(s.name); } } }
運行結果:
chaofn01 chaofn02 Exception in thread "main" java.lang.ClassCastException: java.lang.Integer cannot be cast to com.csu.test1.StringDemo at com.csu.test1.GenericDemo.MyIterator(GenericDemo.java:34) at com.csu.test1.GenericDemo.main(GenericDemo.java:27) chaofn03 chaofn04
在調用MyIterator(List ls) 方法時會發生ClassCastException 異常。而且在編譯時是不會有任何提示,只有運行時會出現,所以使的程序存在安全隱患。
如果使用泛型則會在編譯時提示錯誤,而且在遍歷時不需要強制轉換。如:
import java.util.ArrayList; import java.util.Iterator; import java.util.List; class StringDemo { String name; public StringDemo(String name){ this.name=name; } } public class GenericDemo { public static void main(String[] args) { //創建一個只能保存字符串的ArrayList集合 List<StringDemo> ls=new ArrayList<StringDemo>(); //如果存放其他類型的對象時會出現編譯錯誤 ls.add(new StringDemo("chaofn01")); ls.add(new StringDemo("chaofn02")); ls.add(new StringDemo("chaofn03")); ls.add(new StringDemo("chaofn04")); //下面一行代碼在編譯時會出錯 //ls.add(1000); MyIterator(ls); } public static void MyIterator(List<StringDemo> ls){ Iterator<StringDemo> it=ls.iterator(); while(it.hasNext()){ //不需要強制轉化成StringDemo StringDemo s= it.next(); System.out.println(s.name); } } }
二、自定義泛型類:
除了Java提供了一些類增加了泛型支持外,我們可以自定義泛型支持類。
那么在什么時候定義泛型類呢?
當類中操作的引用數據類型不確定時可以定義泛型類。
格式如下:
class Tools<T> { }
例如:定義一個Tools 類 用來完成打印操作,但是應為不知道要操作的數據類型是什么,所以可以定義成泛型類。具體操作:
//定義一個工具類Tools 2 //因為不知道要操作的類型是什么所以增加泛型支持 3 class Tools<T> 4 { 5 // 包含輸出函數: 6 public void sop(T t) 7 { 8 System.out.println("sop:"+t); 9 } 10 } 11 //定義一個Books 類 12 class Books 13 { 14 private String name ; 15 public Books(String name) 16 { 17 this.name = name ; 18 } 19 // 重寫toString 方法 20 public String toString() 21 { 22 return "name = " + name ; 23 } 24 } 25 public class GenericText 26 { 27 public static void main(String[] args) 28 { 29 // 創建一個Tools 實例tool ,定義 tool 要操作的數據類型為Books 30 Tools<Books> tool = new Tools<Books>() ; 31 // tool 可以操作 Books 類型,還可以操作Integer 類型和String類型。 32 tool.sop(new Books("神雕俠侶")); 33 } }
泛型類定義的泛型,在整個類中有效,如果被方法使用,那么泛型類的對象明確要操作的具體類型后,所有要操作的類型就已經固定了。為了讓不同方法可以操作不同類型,
而且類型還不確定,那么可以將泛型定義在方法上。
三、自定義泛型方法
定義泛型方法格式如下:
public <T> void show(T t) 注意:<>放在修飾符后面,返回值前面 { }
//定義一個工具類Tools 2 //因為不知道要操作的類型是什么所增加泛型支持 3 class Tools<T> 4 { 5 // 包含輸出函數: 6 public void sop(T t) 7 { 8 System.out.println("sop:"+t); 9 } 10 // 定義的泛型方法: 11 public <T> void show (T t) 12 { 13 System.out.println("show:"+t); 14 } 15 } 16 //定義一個Books 類 17 class Books 18 { 19 private String name ; 20 public Books(String name) 21 { 22 this.name = name ; 23 } 24 // 重寫toString 方法 25 public String toString() 26 { 27 return "name = " + name ; 28 } 29 } 30 public class GenericText 31 { 32 public static void main(String[] args) 33 { 34 // 創建一個Tools 實例tool ,定義 tool 要操作的數據類型為Books 35 Tools<Books> tool = new Tools<Books>() ; 36 // tool 可以操作 Books 類型,還可以操作Integer 類型和String類型。 37 tool.sop(new Books("神雕俠侶")); 38 tool.show(new Books("神雕俠侶")) ; 39 // 下面的方法編譯時會報錯》、: 40 tool.sop(1000) ; 41 tool.sop("String") ; 42 43 // 但下面卻不會報錯,並且正常運行。 44 tool.show(1000) ; 45 tool.show("String") ; 46 } 47 }