Java泛型的注意事項以及使用

      爲什麼要用泛型呢?JDK5以前,對象保存到集合中就會失去其特性,取出時通常要程序員手工進行類型的強制轉換,這樣不可避免就會引發程序的一些安全性問題。

      比如:

    

     泛型的作用:

     JDK5中的泛形允許程序員在編寫集合代碼時,就限制集合的處理類型,從而把原來程序運行時可能發生問題,轉變爲編譯時的問題,以此提高程序的可讀性和穩定性(尤其在大型程序中更爲突出)

      注意:泛型是提供給javac編譯器使用的,它用於限定集合的輸入類型,讓編譯器在源代碼級別上,即擋住向集合中插入非法數據。但編譯器編譯完帶有泛形的java程序後,生成的class文件中將不再帶有泛形信息,以此使程序運行效率不受到影響,這個過程稱之爲“擦除”。

     泛形的基本術語,以ArrayList<E>爲例:<>念做typeof
     ArrayList<E>中的E稱爲類型參數變量
     ArrayList<Integer>中的Integer稱爲實際類型參數
     整個稱爲ArrayList<E>泛型類型
     整個ArrayList<Integer>稱爲參數化的類型ParameterizedType
   
     泛型的應用:
     使用迭代器迭代泛形集合中的元素:
     增強for循環迭代泛形集合中的元素:
 
     HashMap中的元素:
import java.util.*;
import java.util.Map.Entry;
public class MapTest{
  public static void main(String [] args){
    Map<Integer,String> map=new HashMap<Integer,String>();
    map.put(1,"x");
    map.put(2,"a");
    map.put(3,"z");
    map.put(4,"s");//添加數據

    /**
    *兩種遍歷Map集合中數據的方法
    */

    //通過set來遍歷
    Set<Integer> set=map.keySet();//返回鍵值的set視圖
    Iterator<Integer> it=set.iterator();//在這裏,如果不加上泛型約束的話,就無法找到需要的類型
    while(it.hasNext()){
       Integer e=it.next();
       String v=map.get(e);
       System.out.println(v);
    }


    //通過Entry來遍歷
    Set<Entry<Integer,String>> entrys=map.entrySet();//返回映射項的set視圖
    Iterator<Entry<Integer,String>> its=entrys.iterator();
    while(its.hasNext()){
       Entry<Integer,String> entry=its.next();
       System.out.println(entry.getKey()+"->"+entry.getValue());
    }
  }
}

¨使用泛形時的幾個常見問題:
        使用泛型時,泛型類型須爲引用類型,不能是基本數據類型
        使用泛型時,兩邊的類型必須一致或者兩邊只有一邊用泛型(爲了保持兼容性)
 
 自定義泛型:Java程序中的普通方法、構造方法和靜態方法中都可以使用泛型。方法使用泛形前,必須對泛形進行聲明,語法:<T>T可以是任意字母,但通常必須要大寫。<T>通常需放在方法的返回值聲明之前。
 下有兩個泛型方法:
 實現交換的泛型方法:
import java.util.Arrays;
import java.util.List;


//編寫泛型方法,實現數組元素交換
public class Swap {
	/**
	 * 將數組中指定兩個位置的元素進行交換
	 */
	public static <T> void swap(T[] arr,Integer pos1,Integer pos2){
		
		T temp=arr[pos1];//記錄第一個值
		arr[pos1]=arr[pos2];//交換
		arr[pos2]=temp;
	}
	public static void main(String[] args) {
		String []arr={"a","b","c"};
		swap(arr,0,arr.length-1);
		List list=Arrays.asList(arr);//把數組轉換爲集合
		System.out.println(list);
	}
}

效果:
 
實現顛倒順序的泛型方法:
import java.util.Arrays;
import java.util.List;


//編寫一個泛型方法,接受一個任意數組,並顛倒數組中的所有元素
public class Reserve {
	public static void main(String[] args) {
		Integer[] arr={1,2,3,4,5,6,7,8,9,0};
		swap(arr);
		List list=Arrays.asList(arr);
		System.out.println(list);
	}
	/**
	 * 泛型方法的定義權限 <T>修飾符  返回值 方法名(參數列表)
	 * @param <T>
	 * @param arr
	 */
	public static <T> void swap(T[] arr){
		int start=0;
		int end=arr.length-1;
		
		while(true){
			if(start>=end){
				break;
			}
			T temp=arr[start];
			arr[start]=arr[end];
			arr[end]=temp;
			
			/*以上的操作時將首位兩個元素不斷的交換,
			 *直到前一個元素的下標大於等於後一個下標爲止
			 */
			start++;
			end--;
		}
	}
}

效果:
 
 如果一個類多處都要用到同一個泛型,這時可以把泛形定義在類上(即類級別的泛型),語法格式如下:

  public class GenericDao<T> {

  privateT field1;

  publicvoid save(T obj){}

  publicT getId(int id){}

  }

注意:

    在類級別上定義的泛型,只對類的非靜態成員有效
    *  靜態方法不能使用類定義的泛形,而應單獨定義泛形
 
 
 
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章