泛型規范在JDK1.5版本中被添加,使用泛型機制編寫的代碼比起隨意使用Object變量然后再進行強制類型轉換的代碼具有更高的安全性和可讀性,同時也更為簡潔。泛型對于集合類尤其有用,例如 ArrayListarray = new ArrayList();。
一、泛型
泛型程序設計(Generic programming)意味著編寫的代碼可以被很多操作不同數據類型的對象所重用。例如
ArrayListarray=newArrayList();
java泛型類和泛型方法,簡單聲明一個ArrayList類型的集合,集合中維護了一個Object引用的數組。而實際使用中集合往往只需要維護某一種特定的非Obj數據類型并對其進行操作,這意味著這ArrayList集合將面對兩個問題:1.對集合中元素進行操作時必須進行強制類型轉換。2.可以向集合中添加任意類型的變量,如果對任意類型變量進行操作時(比如強制類型轉換),容易產生運行時錯誤。
泛型提供了一個很好的解決方案:類型參數(type parameters)。比如ArrayList類這樣來指定類型參數:
ArrayListarray=newArrayList();
這樣生命的ArrayList集合只能接收 String 類型的變量,存儲其他類型變量時會在編譯時報錯。同時不需要進行強制類型轉換。
例如這段代碼將所有元素轉換成大寫:
深入理解java泛型詳解、public class Demo1 {
public static void main(String[] args) {
ArrayList list = new ArrayList(); // 表示該容器只能存儲String類型的數據。
list.add("aa");
list.add("bb");
java中泛型的使用。list.add("cc");
list.add(123); //會編譯時報錯
for(int i = 0 ; i < list.size() ; i++){
String str = list.get(i);
System.out.println("大寫:"+ str.toUpperCase());
int數據類型、}
}
}
二、自定義泛型
1.在方法上自定義泛型
java中泛型、自定義泛型:自定義泛型就是一個數據類型的占位符或者是一個數據類型的變量。
方法上自定義泛型的聲明格式:(與變量一樣需要先聲明,再使用)
修飾符 返回值類型 函數名(使用自定義泛型 …){函數體}
public class Demo {
public static void main(String[] args){
java 泛型類,String str = getData("abc");
}
public static E getData(E o){ //是聲明自定義的泛型 E是返回值類型為E 形參中的E是指傳入參數的類型
return o;
}
Java基本數據類型、}
在方法上自定義泛型需要注意的問題:
1.在泛型中不能使用基本數據類型,如果需要使用基本數據類型,那么就使用基本數據類型對應的包裝類型。
byte —-> Byte
short —-> Short
java簡單數據類型?int —-> Integer
long —-> Long
double —-> Double
float —-> Float
boolean—-> Boolean
數據類型,char —-> Character
在方法上自定義泛型,這個自定義泛型的具體數據類型是在調用該方法的時候傳入實參時確定具體的數據類型的。
自定義泛型只要符合標識符的命名規則即可, 但是自定義泛型我們一般都習慣使用一個大寫字母表示。 T (Type) E (Element).
2.在類上自定義泛型
泛型類的定義格式:
java多線程?class 類名{類體}
泛型類在類的聲明部分引入類型變量,聲明的類型變量可以在整個類中使用。(在類中自定義泛型之后便無需在每個方法中定義)同時泛型類也可以聲明多個類型變量,例如
public class Pair{}
用具體的類型替換類型變量就可以實例化泛型類,例如:
Pair;
以及文章開頭的
ArrayListarray=newArrayList();
實例:重寫一個數組類,實現元素翻轉
class MyArrays{
public void reverse(T[] arr){ //元素翻轉
for(int startIndex = 0, endIndex = arr.length-1 ; startIndex
T temp = arr[startIndex];
arr[startIndex] = arr[endIndex];
arr[endIndex] = temp;
}
}
public String toString(T[] arr){ //重寫toString方法
StringBuilder sb = new StringBuilder();
for(int i = 0 ; i < arr.length ; i++){
if(i==0){
sb.append("["+arr[i]+",");
}else if(i==arr.length-1){
sb.append(arr[i]+"]");
}else{
sb.append(arr[i]+",");
}
}
return sb.toString();
}
public static void print(T[] t){
}
}
public class Demo2 {
public static void main(String[] args){
Integer[] arr = {10,12,14,19};
MyArrays tool = new MyArrays(); //使用泛型定義的類既可以對Integer類型進行操作,同時也可以對String數據類型進行操作,提高了復用性
tool.reverse(arr);
System.out.println("數組的元素:"+tool.toString(arr));
MyArrays tool2 = new MyArrays();
String[] arr2 = {"aaa","bbb","ccc"};
tool2.reverse(arr2);
ArrayList list = new ArrayList();
}
}
泛型類要注意的事項:
在類上自定義泛型的具體數據類型是在使用該類的時候創建對象時候確定的。
如果一個類在類上已經聲明了自定義泛型,如果使用該類創建對象的時候沒有指定泛型的具體數據類型,那么默認為Object類型。
在類上自定義泛型不能作用于靜態的方法,如果靜態的方法需要使用自定義泛型,那么需要在方法上自己聲明使用。
3.在接口上定義泛型
泛型接口的定義格式:
interface 接口名{類體}
泛型接口要注意的事項:
接口上自定義的泛型的具體數據類型是在實現一個接口的時候指定的。
在接口上自定義的泛型如果在實現接口的時候沒有指定具體的數據類型,那么默認為Object類型。
3.延長接口自定義泛型的具體數據類型,那么格式如下:(實現一個接口的時候,還不明確我目前要操作的數據類型,需要等待創建接口實現類的對象的時候才能指定泛型的具體數據類型)
格式: public class Demoimplements Dao{ } //在接口名以及類名之后都要聲明自定義泛型
示例代碼:
interface Dao{
public void add(T t);
}
public class Demo implements Dao{
public static void main(String[] args){
Demo d = new Demo();
}
public void add(T t){
}
}
三、泛型的上下限
泛型中通配符: ?
使用格式:
? super Integer : 只能存儲Integer或者是Integer父類元素。 泛型的下限
? extends Number : 只能存儲Number或者是Number類型的子類數據。 泛型的上限
示例代碼:
public class Demo5 {
public static void main(String[] args) {
ArrayList list1 = new ArrayList();
ArrayList list2 = new ArrayList();
HashSet set = new HashSet();
//getData(set);
}
//泛型的上限
//定義一個函數可以接收接收任意類型的集合對象, 要求接收的集合對象只能存儲Number或者是Number的子類類型數據。
public static void getData(Collection extends Number> c){
}
//泛型的下限
//定義一個函數可以接收接收任意類型的集合對象, 要求接收的集合對象只能存儲Integer或者是Integer的父類類型數據。
public static void print(Collection super Integer> c){
}
}
版权声明:本站所有资料均为网友推荐收集整理而来,仅供学习和研究交流使用。
工作时间:8:00-18:00
客服电话
电子邮件
admin@qq.com
扫码二维码
获取最新动态