java基礎篇--06

========

  1. java中的集合元素被丟進去之後就失去了類型訊息,在當取出的時候就都成爲了Object的類型

    集合加入泛型可以幫助集合記憶這些訊息;

  2. 泛型基礎訊息:

    1》修飾類的時候,寫在類的後方,區別:在調用的時候需要指明具體類型

    List<String>listString = new ArrayList<String>();

2》修飾方法,寫在返回值前,區別:在調用的的時候會根據傳入的參數指明具體類型

private<T> void Test(T a){}

inta;

Stringa;

Test(a);

如上T會根據傳入的a的類型變成int|| String,不需要像類和接口那樣再調用的時候指明

3》修飾變量,可以作爲普通的修飾詞來使用

可以理解:一種特殊的修飾詞,除了類之外,可以看到《》的擺放位置都是和正常的修飾詞一致

泛型+extends

class Apple <T>{
	T info;
}
//這樣寫是錯誤的,算是使用Apple,就必須傳入實際的類型
class Orange extends Apple<T>{
	
}
//這樣傳入實際參數,正確
class Orange1 extends Apple<String>{
	
}
//不傳參數,默認Object,正確,這時會報警告:使用了未經檢查或不安全的操作
class Orange2 extends Apple{
	
}



  1. 泛型+編譯

		//可以看到這裏的泛型很好的限定了List中存儲數據的類型
		List<String> list = new ArrayList<String>();
		List<Integer> list2 = new ArrayList<Integer>();
		//打印結果相等,不管泛型的實際類型參數是什麼,
		//他們在運行的時候總有同樣的類(共一個.class文件)
		System.out.println(list.getClass() == list2.getClass());



  1. 泛型+static

    靜態的東西不能加入<>,因爲在使用的時候無法確認泛型的具體代表的實際類型,原理和3中的第一個例子相似

  2. 泛型+包含關係

    List<String>並不能直接用List<Object>這種類型來接,他們並不是包含關係,是兩個完全不同的類型

  1. 泛型+通配符重要:解決了6中的問題

    1》基礎:List<?>表示可以匹配任何類型

    //以下開始限定範圍了

    2》設置上限:List<?extends String> 表明是一個String類型或者是他的子類,上限String

    3》設置下限:List<?super String> 表明是一個String類型或者是他的父類,下限String

    4》使用範圍:一般在參數中使用,不可直接用於賦值,詳見下8中例子


  1. 不能對任何帶<?>通配符的類型進行復賦值操作(B繼承A)

		List<? extends A> listb = new ArrayList<B>();
		listb.add(new B());

	        //上面的例子是錯的,因爲listb是一個帶通配符的,so,         
                //它是一個不確定的類型,不能進行任何add操作
                //,操作之前可以先進行強制類型轉換


		//可以強制類型轉換成A或者A的子類
		List<A> listA = (List<A>)listb;
		listA.add(new A());
		List<B> listB = (List<B>)listb;
		listB.add(new B());
		
		//注意:強制類型轉換過後就爲”確定的A&B類型“了,就不能在賦值給List<A>
		List<A> listAA = (List<A>)listB;


注意:Bextends A,

List<A>listA =(List<A>)listb;

listA.add(newB());

正確,但是List<A>= List<B>是錯誤的,這兩個類型並不具有包含關係,他們是兩個各自獨立的類型,就像本文6中所說的那樣



  1. 泛型+方法

    private<T> void Test(T a){}

    此時在方法Test中,T即被當做一個普通類型來使用



當方法有多個參數的時候,且參數之間的類型有着關係,這時候需要使用<?>通配符來表達

	<T> void eat(List<? extends T> a,List<T> b){
		System.out.println("eat");
	}
	public static void main(String[] args) {
		Test test = new Test();
		test.eat(new ArrayList<B>(), new ArrayList<A>());
	}



  1. 泛型+構造器(可以理解構造器是類的一種特殊方法,與普通方法的有點區別)

	public <T> Test(T t) {

	}
	<E> void eat(E e){
		
	}
	public static void main(String[] args) {
		String t = "test";
		Test test = new Test(t);
		Test test1 = new <A>Test(new A());
		test.eat(t);
		test1.<A>eat(new A());
	}

         可以看到基本功能一樣,調用的時候都可以選擇指定或者不指定<T>泛型的具體類型


  1. 小知識:

    List<>= List //調用不當(List實際存儲的類型與<>中的不匹配)的時候會導致異常

          List= List<> //丟失TYPE,直接變成List的上限


發佈了38 篇原創文章 · 獲贊 0 · 訪問量 2萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章