什麼時java泛型?java
泛型時jdk1.5版本之後出現的一種對類、方法、接口的一種類型的約束,這種類型的約束是存在與編譯時期的一種約束,在程序的運行時期是沒有泛型的運用。安全
泛型的做用只存在與代碼的編譯時期,運行時沒有泛型的存在ide
泛型即"參數化類型"工具
就是將對象將參數傳遞,爲了可以更好的理解泛型,咱們以上一篇中的分頁工具類來解釋,代碼以下:測試
package com.zs.util; import com.zs.entity.User; import java.util.List; public class PageUtil { private int firstPage; private int proPage; private int currentPage; private int nextPage; private int lastPage; private List<User> list; public PageUtil() { } public PageUtil(int currentPage,int countPage, List<User> list) { this.firstPage = 1; this.currentPage = currentPage; this.lastPage = countPage; this.proPage = this.currentPage == 1 ? 1 : (this.currentPage - 1); this.nextPage = this.currentPage == this.lastPage ? this.currentPage : this.currentPage + 1; this.list = list; } public int getFirstPage() { return firstPage; } public void setFirstPage(int firstPage) { this.firstPage = firstPage; } public int getProPage() { return proPage; } public void setProPage(int proPage) { this.proPage = proPage; } public int getCurrentPage() { return currentPage; } public void setCurrentPage(int currentPage) { this.currentPage = currentPage; } public int getNextPage() { return nextPage; } public void setNextPage(int nextPage) { this.nextPage = nextPage; } public int getLastPage() { return lastPage; } public void setLastPage(int lastPage) { this.lastPage = lastPage; } public List<User> getList() { return list; } public void setList(List<User> list) { this.list = list; } }
這是上一篇中咱們寫的分頁欄的工具,當咱們在前臺點擊了下一頁等跳轉按鈕後,就會發送一個頁數的請求到後臺,後臺將傳遞過來的頁數做爲當前頁,而後獲取當前頁的數據信息,並存入一個集合中,而後經過分頁類的構造方法計算上一頁,下一頁等信息,並將當前頁的信息一併存入工具類裏了。this
上一篇裏例子中,咱們只建立了一個用戶的類,只讀取了user表的數據,那麼若是如今有一個person表,咱們要獲取person表的內容,在一系列操做後獲取了當前頁的內容,咱們要存入List<Person>類型的list中,可是咱們的分頁類PageUtil內的list是一個List<User> 類型的,這樣就出現了類型的不一致,可是分頁的代碼都是同樣的,咱們不能由於這個小緣由,從新建立類,所以咱們就會想,咱們能不能將這個List內的類型看成參數傳遞過去呢,咱們調用方法時,寫的是什麼類型,那麼類內部的List就是什麼類型。spa
這種將對象做爲參數傳遞的行爲就是泛型。3d
仍是前面的pageUtil類,在沒有用泛型時,如今只能傳遞User爲類型的list,那麼咱們將它進行改形成泛型。code
package com.zs.util; import java.util.List; public class PageUtil<T> { private int firstPage; private int proPage; private int currentPage; private int nextPage; private int lastPage; private List<T> list; public PageUtil() { } public PageUtil(int currentPage,int countPage, List<T> list) { this.firstPage = 1; this.currentPage = currentPage; this.lastPage = countPage; this.proPage = this.currentPage == 1 ? 1 : (this.currentPage - 1); this.nextPage = this.currentPage == this.lastPage ? this.currentPage : this.currentPage + 1; this.list = list; } public int getFirstPage() { return firstPage; } public void setFirstPage(int firstPage) { this.firstPage = firstPage; } public int getProPage() { return proPage; } public void setProPage(int proPage) { this.proPage = proPage; } public int getCurrentPage() { return currentPage; } public void setCurrentPage(int currentPage) { this.currentPage = currentPage; } public int getNextPage() { return nextPage; } public void setNextPage(int nextPage) { this.nextPage = nextPage; } public int getLastPage() { return lastPage; } public void setLastPage(int lastPage) { this.lastPage = lastPage; } public List<T> getList() { return list; } public void setList(List<T> list) { this.list = list; } }
如今這個工具類,就能夠保存各類類型的數據集合了,咱們能夠建立多個類型來測試看能不能放進去。這裏由於還要寫泛型的應用,就不作測試了。對象
泛型的應用:
1.泛型類
package com.zs.service; /** * 泛型的類型相似於object類,什麼類型均可以,可是不能夠使用八大基本類型int、double..., * 若是使用八大基本類型的數據,要使用包裝類Integer、Double... * 泛型定義在類上public class 類名<泛型類型1,..>能夠定義多個泛型類型 * @param <E> */ public class Demo1<E> { private E e; public E getE() { return e; } public void setE(E e) { this.e = e; } }
這樣就建立了一個簡單的泛型類。e能夠是任意類型,還能夠傳遞多個類型:
package com.zs.service; import java.util.ArrayList; import java.util.HashMap; import java.util.List; /** * 泛型的類型:T:type E:element K:key V:value這些都指代類型,沒有區別 * @param <E> * @param <K> * @param <Y> */ public class Demo2<E,K,Y> { private List<E> e; private HashMap<K,Y> map; public List<E> getE() { return e; } public void setE(List<E> e) { this.e = e; } public HashMap<K, Y> getMap() { return map; } public void setMap(HashMap<K, Y> map) { this.map = map; } }
能夠看出,在建立demo的對象是,聲明瞭list的類型爲string類型,所以list只能放string類型,若是存放integer類型會報錯,一樣的demo2裏的hashmap的數據類型爲string,integer
在建立對象時,會根據實力化對象時的類型,自動填充內部的E,K,V等,按照順序填充。
2.泛型方法
package com.zs.service; public class Demo3 { /** * 泛型方法的參數類型能夠是任意類型的,可是在聲明方法時,要在返回值前聲明這是個泛型方法<T> * @param t * @param <T> */ public <T> void fun1(T t) { System.out.println("方法執行了" + t); } public static void main(String[] args) { Demo3 demo3 = new Demo3(); demo3.fun1("字符串"); demo3.fun1(111); demo3.fun1(true); /** * 運行結果,能夠看到fun內能夠傳任意類型參數 */ } }
3.泛型接口
package com.zs.service; /** * 若是一個類實現了泛型接口,那麼這個類必須獲得泛型 * @param <T> */ public class Demo4Impl<T> implements Demo4<T> { @Override public void fun(T t) { System.out.println("執行了" + t); } public static void main(String[] args) { Demo4<String> demo4 = new Demo4Impl<>(); /*上面聲明瞭泛型類型爲string類型,所以fun只能傳string類型參數*/ demo4.fun("111"); } }
泛型的做用:
1.提升了程序的安全性(泛型在集合裏的使用)
2.將運行期遇到的問題,提早到了編譯期
3.省去了代碼強轉的麻煩
4.提升了代碼的重用性,實現代碼的公共的封裝
泛型的高級應用:
1.泛型通配符<?>
2.<? extends E>
向下限定,E及其子類
3.<? supper E>
向上限定,E及其父類
舉例說明:
package com.zs.service; import java.util.List; public class Demo5 { /** * 通配符類型傳參,至關於object,能夠傳任意類型 * @param list */ public void fun1(List<?> list) { System.out.println(list); } /** * list的類型能夠是demo3或其全部子類類型的 * @param list */ public void fun2(List<? extends Demo3> list) { System.out.println(list); } /** * list的類型能夠是demo3或其父類類型的 * @param list */ public void fun3(List<? super Demo3> list) { System.out.println(list); } }