Java泛型

1、爲何要有泛型(Generic)?
    1. 解決元素存儲的安全性問題
    2. 解決獲取數據元素時,須要類型強轉的問題java

    泛型,JDK1.5新加入的,解決數據類型的安全性問題,其主要原理是在類聲明時經過一個標識表示類中某個屬性的類型或者是某個方法的返回值及參數類型。這樣在類聲明或實例化時只要指定好須要的具體的類型便可。Java泛型能夠保證若是程序在編譯時沒有發出警告,運行時就不會產生ClassCastException異常。同時,代碼更加簡潔、健壯。git

2、使用泛型
github

3、在集合中使用泛型
    1.對象實例化時不指定泛型,默認爲:Object。
    2.泛型不一樣的引用不能相互賦值。
    3.加入集合中的對象類型必須與指定的泛型類型一致。
安全

    4.靜態方法中不能使用類的泛型。ide

    5.若是泛型類是一個接口或抽象類,則不可建立泛型類的對象。this

    6.不能在catch中使用泛型編碼

    7.從泛型類派生子類,泛型類型需具體化設計

    備註:把一個集合中的內容限制爲一個特定的數據類型,這就是generics背後的核心思想。code

泛型方法對象

    方法,也能夠被泛型化,無論此時定義在其中的類是否是泛型化的。在泛型方法中能夠定義泛型參數,此時,參數的類型就是傳入數據的類型。

泛型方法的格式:
[訪問權限]  <泛型>  返回類型  方法名([泛型標識 參數名稱])  拋出的異常

public class DAO {
    
    public <E>  E get(int id, E e){
        
        E result = null;
        
        return result;
    }
    
}
static <T> void fromArrayToCollection(T[] a, Collection<T> c) {
	for (T o : a) {
		c.add(o);
	}	
}

public static void main(String[] args) {
	Object[] ao = new Object[100];
	Collection<Object> co = new ArrayList<Object>();
	fromArrayToCollection(ao, co);

	String[] sa = new String[20];
	Collection<String> cs = new ArrayList<>();
	fromArrayToCollection(sa, cs);

	Collection<Double> cd = new ArrayList<>();
	// 下面代碼中T是Double類,但sa是String類型,編譯錯誤。
	// fromArrayToCollection(sa, cd);
	// 下面代碼中T是Object類型,sa是String類型,能夠賦值成功。
	fromArrayToCollection(sa, co);  
}

4、泛型和繼承的關係

        若是B是A的一個子類型(子類或者子接口),而G是具備泛型聲明的類或接口,G<B>並非G<A>的子類型!好比:String是Object的子類,可是List<String >並非List<Object>的子類。

public void testGenericAndSubClass() {
	Person[] persons = null;
	Man[] mans = null;
	// 而 Person[] 是 Man[] 的父類.
	persons = mans;

	Person p = mans[0];

	// 在泛型的集合上
	List<Person> personList = null;
	List<Man> manList = null;
	// personList = manList;(報錯)
}

5、通配符

    1.使用類型通配符:? 
        好比:List<?>   ,Map<?,?>
        List<?>是List<String>、List<Object>等各類泛型List的父類。

    2.讀取List<?>的對象list中的元素時,永遠是安全的,由於無論list的真實類型是什麼,它包含的都是Object。

    3.寫入list中的元素時,不行。由於咱們不知道c的元素類型,咱們不能向其中添加對象。
        惟一的例外是null,它是全部類型的成員。
        將任意元素加入到其中不是類型安全的:
        Collection<?> c = new ArrayList<String>();
        c.add(new Object()); // 編譯時錯誤
        由於咱們不知道c的元素類型,咱們不能向其中添加對象。
        add方法有類型參數E做爲集合的元素類型。咱們傳給add的任何參數都必須是一個未知類型的子類。 由於咱們不知道那是什麼類型,因此咱們沒法傳任何東西進去。惟一的例外的是null,它是全部類型的成員。另外一方面,咱們能夠調用get()方法並使用其返回值。返回值是一個未知的類型,可是咱們知道,它老是一個Object。

public static void main(String[] args) {
	List<?> list = null;
	list = new ArrayList<String>();
	list = new ArrayList<Double>();
	//list.add(3);
	list.add(null);
		
	List<String> l1 = new ArrayList<String>();
	List<Integer> l2 = new ArrayList<Integer>();
	l1.add(「Python");
	l2.add(15);
	read(l1);
	read(l2);  }
	static void read(List<?> list){
		for(Object o : list){
			System.out.println(o);
	}
}

    4.有限制的通配符

<?>

容許全部泛型的引用調用

舉例:

<? extends Number>     (無窮小 , Number]

只容許泛型爲Number及Number子類的引用調用

 

<? super Number>      [Number , 無窮大)

只容許泛型爲Number及Number父類的引用調用

 

<? extends Comparable>

只容許泛型爲實現Comparable接口的實現類的引用調用

public static void printCollection3(Collection<? extends Person> coll){
	 
	Iterator<?> iterator  = coll.iterator();
	while(iterator.hasNext()){
		System.out.println(iterator.next());
	}   
}

public static void printCollection4(Collection<? super Person> coll){
	Iterator<?> iterator  = coll.iterator();
	while(iterator.hasNext()){
		System.out.println(iterator.next());
	}  

}

範例:泛型應用


    用戶在設計類的時候每每會使用類的關聯關係,例如,一我的中能夠定義一個信息的屬性,可是一我的可能有各類各樣的信息(如聯繫方式、基本信息等),因此此信息屬性的類型就能夠經過泛型進行聲明,而後只要設計相應的信息類便可。

public interface Info{		// 只有此接口的子類纔是表示人的信息

}

public class Contact implements Info{	// 表示聯繫方式
	private String address ;	// 聯繫地址
	private String telephone ;	// 聯繫方式
	private String zipcode ;	// 郵政編碼
	
	public Contact(String address,String telephone,String zipcode){
		this.address = address;
		this.telephone = telephone;
		this.zipcode = zipcode;
	}
	
	public void setAddress(String address){
		this.address = address ;
	}
	public void setTelephone(String telephone){
		this.telephone = telephone ;
	}
	public void setZipcode(String zipcode){
		this.zipcode = zipcode;
	}
	public String getAddress(){
		return this.address ;
	}
	public String getTelephone(){
		return this.telephone ;
	}
	public String getZipcode(){
		return this.zipcode;
	}
	
	@Override
	public String toString() {
		return "Contact [address=" + address + ", telephone=" + telephone
				+ ", zipcode=" + zipcode + "]";
	}
	
}

public class Introduction implements Info{
	private String name ;		// 姓名
	private String sex ;		// 性別
	private int age ;			// 年齡
	
	public Introduction(String name,String sex,int age){
		this.name = name;
		this.sex = sex;
		this.age = age;
	}
	
	public void setName(String name){
		this.name = name ;
	}
	public void setSex(String sex){
		this.sex = sex ;
	}
	public void setAge(int age){
		this.age = age ;
	}
	public String getName(){
		return this.name ;
	}
	public String getSex(){
		return this.sex ;
	}
	public int getAge(){
		return this.age ;
	}
	
	@Override
	public String toString() {
		return "Introduction [name=" + name + ", sex=" + sex + ", age=" + age
				+ "]";
	}
	
}

public class Person<T extends Info>{
	
	private T info ;
	
	public Person(T info){		// 經過構造方法設置信息屬性內容
		this.info = info;
	}
	public void setInfo(T info){
		this.info = info ;
	}
	public T getInfo(){
		return info ;
	}
	
	@Override
	public String toString() {
		return "Person [info=" + info + "]";
	}
	
//	public String toString(){	// 覆寫Object類中的toString()方法
//		return this.info.toString() ;
//	}
}

public class GenericPerson{
	public static void main(String args[]){
		Person<Contact> per = null ;		// 聲明Person對象
		per = new Person<Contact>(new Contact("北京市","01088888888","666666")) ;
		System.out.println(per);
		
		Person<Introduction> per2 = null ;		// 聲明Person對象
		per2 = new Person<Introduction>(new Introduction("王尼瑪","男",27));
		System.out.println(per2) ;
	}
}

  GitHub地址:https://github.com/leebingbin/  

相關文章
相關標籤/搜索